fp.isa revision 11671:520509f3e66c
16657Snate@binkert.org// -*- mode:c++ -*-
26657Snate@binkert.org
310972Sdavid.hashe@amd.com// Copyright (c) 2010-2011,2016 ARM Limited
46657Snate@binkert.org// All rights reserved
56657Snate@binkert.org//
66657Snate@binkert.org// The license below extends only to copyright in the software and shall
76657Snate@binkert.org// not be construed as granting a license to any other intellectual
86657Snate@binkert.org// property including but not limited to intellectual property relating
96657Snate@binkert.org// to a hardware implementation of the functionality of the software
106657Snate@binkert.org// licensed hereunder.  You may use the software subject to the license
116657Snate@binkert.org// terms below provided that you ensure that this notice is replicated
126657Snate@binkert.org// unmodified and in its entirety in all distributions of the software,
136657Snate@binkert.org// modified or unmodified, in source code or in binary form.
146657Snate@binkert.org//
156657Snate@binkert.org// Copyright (c) 2007-2008 The Florida State University
166657Snate@binkert.org// All rights reserved.
176657Snate@binkert.org//
186657Snate@binkert.org// Redistribution and use in source and binary forms, with or without
196657Snate@binkert.org// modification, are permitted provided that the following conditions are
206657Snate@binkert.org// met: redistributions of source code must retain the above copyright
216657Snate@binkert.org// notice, this list of conditions and the following disclaimer;
226657Snate@binkert.org// redistributions in binary form must reproduce the above copyright
236657Snate@binkert.org// notice, this list of conditions and the following disclaimer in the
246657Snate@binkert.org// documentation and/or other materials provided with the distribution;
256657Snate@binkert.org// neither the name of the copyright holders nor the names of its
266657Snate@binkert.org// contributors may be used to endorse or promote products derived from
276657Snate@binkert.org// this software without specific prior written permission.
286657Snate@binkert.org//
296999Snate@binkert.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
306657Snate@binkert.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
316657Snate@binkert.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
326657Snate@binkert.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
336657Snate@binkert.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
348189SLisa.Hsu@amd.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
356657Snate@binkert.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
369499Snilay@cs.wisc.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
379499Snilay@cs.wisc.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
389364Snilay@cs.wisc.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
397055Snate@binkert.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
406882SBrad.Beckmann@amd.com//
416882SBrad.Beckmann@amd.com// Authors: Stephen Hines
428191SLisa.Hsu@amd.com
436882SBrad.Beckmann@amd.com////////////////////////////////////////////////////////////////////
446882SBrad.Beckmann@amd.com//
459102SNuwan.Jayasena@amd.com// Floating Point operate instructions
4611084Snilay@cs.wisc.edu//
479366Snilay@cs.wisc.edu
489499Snilay@cs.wisc.eduoutput header {{
499499Snilay@cs.wisc.edu
509499Snilay@cs.wisc.edu    template<template <typename T> class Base>
516882SBrad.Beckmann@amd.com    StaticInstPtr
526657Snate@binkert.org    newNeonMemInst(const unsigned size,
536657Snate@binkert.org                   const ExtMachInst &machInst,
546657Snate@binkert.org                   const RegIndex dest, const RegIndex ra,
556657Snate@binkert.org                   const uint32_t imm, const unsigned extraMemFlags)
5610311Snilay@cs.wisc.edu    {
5710311Snilay@cs.wisc.edu        switch (size) {
5810311Snilay@cs.wisc.edu          case 0:
5910311Snilay@cs.wisc.edu            return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags);
606657Snate@binkert.org          case 1:
6110311Snilay@cs.wisc.edu            return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags);
629366Snilay@cs.wisc.edu          case 2:
637839Snilay@cs.wisc.edu            return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags);
646657Snate@binkert.org          case 3:
656882SBrad.Beckmann@amd.com            return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags);
6610308Snilay@cs.wisc.edu          default:
6710308Snilay@cs.wisc.edu            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
686882SBrad.Beckmann@amd.com        }
6910308Snilay@cs.wisc.edu    }
7010308Snilay@cs.wisc.edu
7110308Snilay@cs.wisc.edu    template<template <typename T> class Base>
7210308Snilay@cs.wisc.edu    StaticInstPtr
7310308Snilay@cs.wisc.edu    newNeonMixInst(const unsigned size,
749366Snilay@cs.wisc.edu                   const ExtMachInst &machInst,
759366Snilay@cs.wisc.edu                   const RegIndex dest, const RegIndex op1,
766657Snate@binkert.org                   const uint32_t step)
776657Snate@binkert.org    {
786657Snate@binkert.org        switch (size) {
796657Snate@binkert.org          case 0:
809104Shestness@cs.utexas.edu            return new Base<uint8_t>(machInst, dest, op1, step);
816657Snate@binkert.org          case 1:
826657Snate@binkert.org            return new Base<uint16_t>(machInst, dest, op1, step);
836657Snate@binkert.org          case 2:
8410311Snilay@cs.wisc.edu            return new Base<uint32_t>(machInst, dest, op1, step);
8510311Snilay@cs.wisc.edu          case 3:
8610311Snilay@cs.wisc.edu            return new Base<uint64_t>(machInst, dest, op1, step);
8710311Snilay@cs.wisc.edu          default:
886657Snate@binkert.org            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
897839Snilay@cs.wisc.edu        }
907839Snilay@cs.wisc.edu    }
9110972Sdavid.hashe@amd.com
9210972Sdavid.hashe@amd.com}};
9310972Sdavid.hashe@amd.com
946657Snate@binkert.orglet {{
956657Snate@binkert.org    header_output = '''
966657Snate@binkert.org    StaticInstPtr
976657Snate@binkert.org    decodeNeonMem(ExtMachInst machInst);
986657Snate@binkert.org
996657Snate@binkert.org    StaticInstPtr
1006657Snate@binkert.org    decodeNeonData(ExtMachInst machInst);
1016657Snate@binkert.org    '''
1026657Snate@binkert.org
1036657Snate@binkert.org    decoder_output = '''
1046657Snate@binkert.org    StaticInstPtr
1056657Snate@binkert.org    decodeNeonMem(ExtMachInst machInst)
1066657Snate@binkert.org    {
1076657Snate@binkert.org        const uint32_t b = bits(machInst, 11, 8);
1086657Snate@binkert.org        const bool single = bits(machInst, 23);
1096657Snate@binkert.org        const bool singleAll = single && (bits(b, 3, 2) == 3);
1106657Snate@binkert.org        const bool load = bits(machInst, 21);
1116657Snate@binkert.org
1126779SBrad.Beckmann@amd.com        unsigned width = 0;
1136657Snate@binkert.org
1146657Snate@binkert.org        if (single) {
1156657Snate@binkert.org            width = bits(b, 1, 0) + 1;
1166657Snate@binkert.org        } else {
1176657Snate@binkert.org            switch (bits(b, 3, 1)) {
1186657Snate@binkert.org              case 0x0: width = 4;
1196657Snate@binkert.org                break;
1206657Snate@binkert.org              case 0x1: width = (b & 0x1) ? 2 : 1;
1216657Snate@binkert.org                break;
12210972Sdavid.hashe@amd.com              case 0x2: width = 3;
12310972Sdavid.hashe@amd.com                break;
12410972Sdavid.hashe@amd.com              case 0x3: width = 1;
1259104Shestness@cs.utexas.edu                break;
1269104Shestness@cs.utexas.edu              case 0x4: width = 2;
1279104Shestness@cs.utexas.edu                break;
1289104Shestness@cs.utexas.edu              case 0x5:
1296657Snate@binkert.org                if ((b & 0x1) == 0) {
1306657Snate@binkert.org                    width = 1;
1316657Snate@binkert.org                    break;
1326657Snate@binkert.org                }
1336657Snate@binkert.org                // Fall through on purpose.
1346657Snate@binkert.org              default:
1356657Snate@binkert.org                return new Unknown(machInst);
1366657Snate@binkert.org            }
1376657Snate@binkert.org        }
1386657Snate@binkert.org        assert(width > 0 && width <= 4);
1396657Snate@binkert.org
1406657Snate@binkert.org        const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0);
1416657Snate@binkert.org        const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16);
14210307Snilay@cs.wisc.edu        const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) |
1436657Snate@binkert.org                                                 bits(machInst, 22) << 4);
1446657Snate@binkert.org        const uint32_t type = bits(machInst, 11, 8);
1457839Snilay@cs.wisc.edu        uint32_t size = 0;
1467839Snilay@cs.wisc.edu        uint32_t align = TLB::MustBeOne;
1477839Snilay@cs.wisc.edu        unsigned inc = 1;
1487839Snilay@cs.wisc.edu        unsigned regs = 1;
1497839Snilay@cs.wisc.edu        unsigned lane = 0;
1507839Snilay@cs.wisc.edu        if (single) {
1517839Snilay@cs.wisc.edu            if (singleAll) {
1527839Snilay@cs.wisc.edu                size = bits(machInst, 7, 6);
1537839Snilay@cs.wisc.edu                bool t = bits(machInst, 5);
1547839Snilay@cs.wisc.edu                align = size | TLB::AllowUnaligned;
15510968Sdavid.hashe@amd.com                if (width == 1) {
15610968Sdavid.hashe@amd.com                    regs = t ? 2 : 1;
15710968Sdavid.hashe@amd.com                    inc = 1;
15810968Sdavid.hashe@amd.com                } else {
15910968Sdavid.hashe@amd.com                    regs = width;
16010968Sdavid.hashe@amd.com                    inc = t ? 2 : 1;
16110968Sdavid.hashe@amd.com                }
1627839Snilay@cs.wisc.edu                switch (width) {
1636657Snate@binkert.org                  case 1:
1646657Snate@binkert.org                  case 2:
1656657Snate@binkert.org                    if (bits(machInst, 4))
1666657Snate@binkert.org                        align = size + width - 1;
1676657Snate@binkert.org                    break;
1686657Snate@binkert.org                  case 3:
1696657Snate@binkert.org                    break;
1706657Snate@binkert.org                  case 4:
1716657Snate@binkert.org                    if (size == 3) {
1726657Snate@binkert.org                        if (bits(machInst, 4) == 0)
1736657Snate@binkert.org                            return new Unknown(machInst);
1746657Snate@binkert.org                        size = 2;
1756657Snate@binkert.org                        align = 0x4;
1766657Snate@binkert.org                    } else if (size == 2) {
1776657Snate@binkert.org                        if (bits(machInst, 4))
1786657Snate@binkert.org                            align = 0x3;
1796657Snate@binkert.org                    } else {
1806657Snate@binkert.org                        if (bits(machInst, 4))
1816657Snate@binkert.org                            align = size + 2;
1826657Snate@binkert.org                    }
1836657Snate@binkert.org                    break;
1846657Snate@binkert.org                }
1856657Snate@binkert.org            } else {
1866657Snate@binkert.org                size = bits(machInst, 11, 10);
1876657Snate@binkert.org                align = size | TLB::AllowUnaligned;
1886657Snate@binkert.org                regs = width;
1896657Snate@binkert.org                unsigned indexAlign = bits(machInst, 7, 4);
1906657Snate@binkert.org                // If width is 1, inc is always 1. That's overridden later.
1916657Snate@binkert.org                switch (size) {
1926657Snate@binkert.org                  case 0:
19310963Sdavid.hashe@amd.com                    inc = 1;
19410963Sdavid.hashe@amd.com                    lane = bits(indexAlign, 3, 1);
19510963Sdavid.hashe@amd.com                    break;
19610963Sdavid.hashe@amd.com                  case 1:
19710963Sdavid.hashe@amd.com                    inc = bits(indexAlign, 1) ? 2 : 1;
19810963Sdavid.hashe@amd.com                    lane = bits(indexAlign, 3, 2);
19911095Snilay@cs.wisc.edu                    break;
20010963Sdavid.hashe@amd.com                  case 2:
20110963Sdavid.hashe@amd.com                    inc = bits(indexAlign, 2) ? 2 : 1;
20210963Sdavid.hashe@amd.com                    lane = bits(indexAlign, 3);
20310963Sdavid.hashe@amd.com                    break;
20410963Sdavid.hashe@amd.com                }
20510963Sdavid.hashe@amd.com                // Override inc for width of 1.
20610963Sdavid.hashe@amd.com                if (width == 1) {
20710963Sdavid.hashe@amd.com                    inc = 1;
2089219Spower.jg@gmail.com                }
2096877Ssteve.reinhardt@amd.com                switch (width) {
2106657Snate@binkert.org                  case 1:
2119219Spower.jg@gmail.com                    switch (size) {
2126657Snate@binkert.org                      case 0:
2139219Spower.jg@gmail.com                        break;
2146657Snate@binkert.org                      case 1:
2156877Ssteve.reinhardt@amd.com                        if (bits(indexAlign, 0))
2166999Snate@binkert.org                            align = 1;
2176877Ssteve.reinhardt@amd.com                        break;
21810308Snilay@cs.wisc.edu                      case 2:
2196877Ssteve.reinhardt@amd.com                        if (bits(indexAlign, 1, 0))
2206877Ssteve.reinhardt@amd.com                            align = 2;
22110308Snilay@cs.wisc.edu                        break;
2226877Ssteve.reinhardt@amd.com                    }
2236877Ssteve.reinhardt@amd.com                    break;
2246877Ssteve.reinhardt@amd.com                  case 2:
2256877Ssteve.reinhardt@amd.com                    if (bits(indexAlign, 0))
2266877Ssteve.reinhardt@amd.com                        align = size + 1;
2276877Ssteve.reinhardt@amd.com                    break;
2286877Ssteve.reinhardt@amd.com                  case 3:
2299338SAndreas.Sandberg@arm.com                    break;
2306877Ssteve.reinhardt@amd.com                  case 4:
2316877Ssteve.reinhardt@amd.com                    switch (size) {
2326877Ssteve.reinhardt@amd.com                      case 0:
2336877Ssteve.reinhardt@amd.com                      case 1:
23410308Snilay@cs.wisc.edu                        if (bits(indexAlign, 0))
23510308Snilay@cs.wisc.edu                            align = size + 2;
23610308Snilay@cs.wisc.edu                        break;
23710308Snilay@cs.wisc.edu                      case 2:
23811084Snilay@cs.wisc.edu                        if (bits(indexAlign, 0))
2396882SBrad.Beckmann@amd.com                            align = bits(indexAlign, 1, 0) + 2;
24010308Snilay@cs.wisc.edu                        break;
24110308Snilay@cs.wisc.edu                    }
2426882SBrad.Beckmann@amd.com                    break;
2436882SBrad.Beckmann@amd.com                }
2446882SBrad.Beckmann@amd.com            }
2456882SBrad.Beckmann@amd.com            if (size == 0x3) {
24611021Sjthestness@gmail.com                return new Unknown(machInst);
2476877Ssteve.reinhardt@amd.com            }
2486877Ssteve.reinhardt@amd.com        } else {
24910917Sbrandon.potter@amd.com            size = bits(machInst, 7, 6);
2506877Ssteve.reinhardt@amd.com            align = bits(machInst, 5, 4);
2516657Snate@binkert.org            if (align == 0) {
2526657Snate@binkert.org                // @align wasn't specified, so alignment can be turned off.
2536999Snate@binkert.org                align = size | TLB::AllowUnaligned;
2546657Snate@binkert.org            } else {
2556657Snate@binkert.org                align = align + 2;
2566657Snate@binkert.org            }
2576657Snate@binkert.org            switch (width) {
2587007Snate@binkert.org              case 1:
2596657Snate@binkert.org                switch (type) {
2606657Snate@binkert.org                  case 0x7: regs = 1;
2616657Snate@binkert.org                    break;
2626657Snate@binkert.org                  case 0xa: regs = 2;
2636657Snate@binkert.org                    break;
2647007Snate@binkert.org                  case 0x6: regs = 3;
2657007Snate@binkert.org                    break;
2666657Snate@binkert.org                  case 0x2: regs = 4;
2677002Snate@binkert.org                    break;
2687002Snate@binkert.org                  default:
2697002Snate@binkert.org                    return new Unknown(machInst);
2707002Snate@binkert.org                }
2716657Snate@binkert.org                break;
2726657Snate@binkert.org              case 2:
2738229Snate@binkert.org                // Regs doesn't behave exactly as it does in the manual
2748229Snate@binkert.org                // because they loop over regs registers twice and we break
2758229Snate@binkert.org                // it down in the macroop.
27610972Sdavid.hashe@amd.com                switch (type) {
2776657Snate@binkert.org                  case 0x8: regs = 2; inc = 1;
2786657Snate@binkert.org                    break;
2796657Snate@binkert.org                  case 0x9: regs = 2; inc = 2;
2806657Snate@binkert.org                    break;
2816793SBrad.Beckmann@amd.com                  case 0x3: regs = 4; inc = 2;
2826657Snate@binkert.org                    break;
28310311Snilay@cs.wisc.edu                  default:
2846657Snate@binkert.org                    return new Unknown(machInst);
2856657Snate@binkert.org                }
2866657Snate@binkert.org                break;
2877002Snate@binkert.org              case 3:
2886657Snate@binkert.org                regs = 3;
2897007Snate@binkert.org                switch (type) {
2907007Snate@binkert.org                  case 0x4: inc = 1;
2919271Snilay@cs.wisc.edu                    break;
2926877Ssteve.reinhardt@amd.com                  case 0x5: inc = 2;;
2936877Ssteve.reinhardt@amd.com                    break;
2946657Snate@binkert.org                  default:
2956877Ssteve.reinhardt@amd.com                    return new Unknown(machInst);
29610311Snilay@cs.wisc.edu                }
29711084Snilay@cs.wisc.edu                break;
29811084Snilay@cs.wisc.edu              case 4:
29911021Sjthestness@gmail.com                regs = 4;
3009745Snilay@cs.wisc.edu                switch (type) {
3017002Snate@binkert.org                  case 0: inc = 1;
3026657Snate@binkert.org                    break;
30310012Snilay@cs.wisc.edu                  case 1: inc = 2;
3049745Snilay@cs.wisc.edu                    break;
3059745Snilay@cs.wisc.edu                  default:
3069745Snilay@cs.wisc.edu                    return new Unknown(machInst);
3078683Snilay@cs.wisc.edu                }
3088683Snilay@cs.wisc.edu                break;
3097007Snate@binkert.org            }
31010524Snilay@cs.wisc.edu        }
3119302Snilay@cs.wisc.edu
3129745Snilay@cs.wisc.edu        if (load) {
3139745Snilay@cs.wisc.edu            // Load instructions.
31411061Snilay@cs.wisc.edu            if (single) {
3159745Snilay@cs.wisc.edu                return new VldSingle(machInst, singleAll, width, rn, vd,
31611061Snilay@cs.wisc.edu                                     regs, inc, size, align, rm, lane);
3179745Snilay@cs.wisc.edu            } else {
3186657Snate@binkert.org                return new VldMult(machInst, width, rn, vd,
3196657Snate@binkert.org                                   regs, inc, size, align, rm);
3206657Snate@binkert.org            }
3216657Snate@binkert.org        } else {
3226657Snate@binkert.org            // Store instructions.
3236657Snate@binkert.org            if (single) {
3246882SBrad.Beckmann@amd.com                if (singleAll) {
3256882SBrad.Beckmann@amd.com                    return new Unknown(machInst);
3266882SBrad.Beckmann@amd.com                } else {
3276882SBrad.Beckmann@amd.com                    return new VstSingle(machInst, false, width, rn, vd,
3286657Snate@binkert.org                                         regs, inc, size, align, rm, lane);
3296657Snate@binkert.org                }
3307007Snate@binkert.org            } else {
3317839Snilay@cs.wisc.edu                return new VstMult(machInst, width, rn, vd,
3327839Snilay@cs.wisc.edu                                   regs, inc, size, align, rm);
3337839Snilay@cs.wisc.edu            }
3347839Snilay@cs.wisc.edu        }
3357839Snilay@cs.wisc.edu        return new Unknown(machInst);
3367839Snilay@cs.wisc.edu    }
3377839Snilay@cs.wisc.edu    '''
3387839Snilay@cs.wisc.edu
3397839Snilay@cs.wisc.edu    decoder_output += '''
3407839Snilay@cs.wisc.edu    static StaticInstPtr
3417839Snilay@cs.wisc.edu    decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
3427839Snilay@cs.wisc.edu    {
34311025Snilay@cs.wisc.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
3447007Snate@binkert.org        const uint32_t a = bits(machInst, 11, 8);
3457007Snate@binkert.org        const bool b = bits(machInst, 4);
3467007Snate@binkert.org        const uint32_t c = bits(machInst, 21, 20);
3477007Snate@binkert.org        const IntRegIndex vd =
3487839Snilay@cs.wisc.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
3497839Snilay@cs.wisc.edu                               (bits(machInst, 22) << 4)));
3507839Snilay@cs.wisc.edu        const IntRegIndex vn =
3517839Snilay@cs.wisc.edu            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
3527839Snilay@cs.wisc.edu                               (bits(machInst, 7) << 4)));
3537839Snilay@cs.wisc.edu        const IntRegIndex vm =
3547839Snilay@cs.wisc.edu            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
3557839Snilay@cs.wisc.edu                               (bits(machInst, 5) << 4)));
3567839Snilay@cs.wisc.edu        const unsigned size = bits(machInst, 21, 20);
3577839Snilay@cs.wisc.edu        const bool q = bits(machInst, 6);
3587839Snilay@cs.wisc.edu        if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1)))
3597839Snilay@cs.wisc.edu            return new Unknown(machInst);
36011025Snilay@cs.wisc.edu        switch (a) {
3617007Snate@binkert.org          case 0x0:
3629745Snilay@cs.wisc.edu            if (b) {
3639745Snilay@cs.wisc.edu                if (u) {
3649745Snilay@cs.wisc.edu                    return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
3659745Snilay@cs.wisc.edu                            q, size, machInst, vd, vn, vm);
3669745Snilay@cs.wisc.edu                } else {
3679745Snilay@cs.wisc.edu                    return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
3686657Snate@binkert.org                            q, size, machInst, vd, vn, vm);
3697007Snate@binkert.org                }
3706657Snate@binkert.org            } else {
3716657Snate@binkert.org                if (size == 3)
3726657Snate@binkert.org                    return new Unknown(machInst);
3736657Snate@binkert.org                return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
3746657Snate@binkert.org                        q, u, size, machInst, vd, vn, vm);
3756657Snate@binkert.org            }
3766657Snate@binkert.org          case 0x1:
3776657Snate@binkert.org            if (!b) {
3787839Snilay@cs.wisc.edu                return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
3797839Snilay@cs.wisc.edu                        q, u, size, machInst, vd, vn, vm);
3807839Snilay@cs.wisc.edu            } else {
3817839Snilay@cs.wisc.edu                if (u) {
3827839Snilay@cs.wisc.edu                    switch (c) {
3837839Snilay@cs.wisc.edu                      case 0:
3847839Snilay@cs.wisc.edu                        if (q) {
3857839Snilay@cs.wisc.edu                            return new VeorQ<uint64_t>(machInst, vd, vn, vm);
3867839Snilay@cs.wisc.edu                        } else {
3877839Snilay@cs.wisc.edu                            return new VeorD<uint64_t>(machInst, vd, vn, vm);
3887839Snilay@cs.wisc.edu                        }
3897839Snilay@cs.wisc.edu                      case 1:
3907839Snilay@cs.wisc.edu                        if (q) {
3917839Snilay@cs.wisc.edu                            return new VbslQ<uint64_t>(machInst, vd, vn, vm);
3927839Snilay@cs.wisc.edu                        } else {
3937839Snilay@cs.wisc.edu                            return new VbslD<uint64_t>(machInst, vd, vn, vm);
39410121Snilay@cs.wisc.edu                        }
3956657Snate@binkert.org                      case 2:
3966657Snate@binkert.org                        if (q) {
3976657Snate@binkert.org                            return new VbitQ<uint64_t>(machInst, vd, vn, vm);
3986657Snate@binkert.org                        } else {
3997839Snilay@cs.wisc.edu                            return new VbitD<uint64_t>(machInst, vd, vn, vm);
4007839Snilay@cs.wisc.edu                        }
4017839Snilay@cs.wisc.edu                      case 3:
40210121Snilay@cs.wisc.edu                        if (q) {
40310121Snilay@cs.wisc.edu                            return new VbifQ<uint64_t>(machInst, vd, vn, vm);
40411025Snilay@cs.wisc.edu                        } else {
4057839Snilay@cs.wisc.edu                            return new VbifD<uint64_t>(machInst, vd, vn, vm);
4067839Snilay@cs.wisc.edu                        }
4077839Snilay@cs.wisc.edu                    }
40810121Snilay@cs.wisc.edu                } else {
40911025Snilay@cs.wisc.edu                    switch (c) {
4107839Snilay@cs.wisc.edu                      case 0:
4117839Snilay@cs.wisc.edu                        if (q) {
4127839Snilay@cs.wisc.edu                            return new VandQ<uint64_t>(machInst, vd, vn, vm);
41310121Snilay@cs.wisc.edu                        } else {
41411025Snilay@cs.wisc.edu                            return new VandD<uint64_t>(machInst, vd, vn, vm);
4157839Snilay@cs.wisc.edu                        }
4167839Snilay@cs.wisc.edu                      case 1:
4177839Snilay@cs.wisc.edu                        if (q) {
41811025Snilay@cs.wisc.edu                            return new VbicQ<uint64_t>(machInst, vd, vn, vm);
4196657Snate@binkert.org                        } else {
4206657Snate@binkert.org                            return new VbicD<uint64_t>(machInst, vd, vn, vm);
4216657Snate@binkert.org                        }
4226657Snate@binkert.org                      case 2:
4237007Snate@binkert.org                        if (vn == vm) {
4246657Snate@binkert.org                            if (q) {
4256657Snate@binkert.org                                return new VmovQ<uint64_t>(
4269273Snilay@cs.wisc.edu                                        machInst, vd, vn, vm);
42710305Snilay@cs.wisc.edu                            } else {
4286657Snate@binkert.org                                return new VmovD<uint64_t>(
4296657Snate@binkert.org                                        machInst, vd, vn, vm);
4306657Snate@binkert.org                            }
4317007Snate@binkert.org                        } else {
4326657Snate@binkert.org                            if (q) {
4336657Snate@binkert.org                                return new VorrQ<uint64_t>(
4349219Spower.jg@gmail.com                                        machInst, vd, vn, vm);
4356657Snate@binkert.org                            } else {
4366657Snate@binkert.org                                return new VorrD<uint64_t>(
4376999Snate@binkert.org                                        machInst, vd, vn, vm);
4386657Snate@binkert.org                            }
4396657Snate@binkert.org                        }
4406657Snate@binkert.org                      case 3:
4416657Snate@binkert.org                        if (q) {
4427007Snate@binkert.org                            return new VornQ<uint64_t>(
4436657Snate@binkert.org                                    machInst, vd, vn, vm);
4446657Snate@binkert.org                        } else {
4456657Snate@binkert.org                            return new VornD<uint64_t>(
4466657Snate@binkert.org                                    machInst, vd, vn, vm);
4476657Snate@binkert.org                        }
4488946Sandreas.hansson@arm.com                    }
4498946Sandreas.hansson@arm.com                }
4508946Sandreas.hansson@arm.com            }
4517832Snate@binkert.org          case 0x2:
4527002Snate@binkert.org            if (b) {
4537002Snate@binkert.org                if (u) {
45410972Sdavid.hashe@amd.com                    return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
4557002Snate@binkert.org                            q, size, machInst, vd, vn, vm);
4568641Snate@binkert.org                } else {
4577056Snate@binkert.org                    return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
45810972Sdavid.hashe@amd.com                            q, size, machInst, vd, vn, vm);
45910972Sdavid.hashe@amd.com                }
46010972Sdavid.hashe@amd.com            } else {
46110972Sdavid.hashe@amd.com                if (size == 3)
46210972Sdavid.hashe@amd.com                    return new Unknown(machInst);
4636657Snate@binkert.org                return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
4648229Snate@binkert.org                        q, u, size, machInst, vd, vn, vm);
4656657Snate@binkert.org            }
4666657Snate@binkert.org          case 0x3:
46711108Sdavid.hashe@amd.com            if (b) {
46810972Sdavid.hashe@amd.com                return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
4699219Spower.jg@gmail.com                        q, u, size, machInst, vd, vn, vm);
4709219Spower.jg@gmail.com            } else {
4719219Spower.jg@gmail.com                return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
4729219Spower.jg@gmail.com                        q, u, size, machInst, vd, vn, vm);
4739219Spower.jg@gmail.com            }
4747002Snate@binkert.org          case 0x4:
4757002Snate@binkert.org            if (b) {
4766657Snate@binkert.org                if (u) {
4776657Snate@binkert.org                    return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
4786657Snate@binkert.org                            q, size, machInst, vd, vm, vn);
4796657Snate@binkert.org                } else {
4806657Snate@binkert.org                    return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
4816793SBrad.Beckmann@amd.com                            q, size, machInst, vd, vm, vn);
4826657Snate@binkert.org                }
4836657Snate@binkert.org            } else {
4846657Snate@binkert.org                return decodeNeonUSThreeReg<VshlD, VshlQ>(
48510121Snilay@cs.wisc.edu                        q, u, size, machInst, vd, vm, vn);
48610121Snilay@cs.wisc.edu            }
4876657Snate@binkert.org          case 0x5:
4886877Ssteve.reinhardt@amd.com            if (b) {
4896877Ssteve.reinhardt@amd.com                if (u) {
4906877Ssteve.reinhardt@amd.com                    return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
4916877Ssteve.reinhardt@amd.com                            q, size, machInst, vd, vm, vn);
4926877Ssteve.reinhardt@amd.com                } else {
4936877Ssteve.reinhardt@amd.com                    return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
4946657Snate@binkert.org                            q, size, machInst, vd, vm, vn);
4959745Snilay@cs.wisc.edu                }
4969745Snilay@cs.wisc.edu            } else {
4976657Snate@binkert.org                return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
4987007Snate@binkert.org                        q, u, size, machInst, vd, vm, vn);
4996657Snate@binkert.org            }
5009801Snilay@cs.wisc.edu          case 0x6:
5019801Snilay@cs.wisc.edu            if (b) {
5026657Snate@binkert.org                return decodeNeonUSThreeReg<VminD, VminQ>(
5039801Snilay@cs.wisc.edu                        q, u, size, machInst, vd, vn, vm);
5049801Snilay@cs.wisc.edu            } else {
5059801Snilay@cs.wisc.edu                return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
5067007Snate@binkert.org                        q, u, size, machInst, vd, vn, vm);
5076657Snate@binkert.org            }
5086877Ssteve.reinhardt@amd.com          case 0x7:
5096877Ssteve.reinhardt@amd.com            if (b) {
5106657Snate@binkert.org                return decodeNeonUSThreeReg<VabaD, VabaQ>(
51110078Snilay@cs.wisc.edu                        q, u, size, machInst, vd, vn, vm);
51210078Snilay@cs.wisc.edu            } else {
51310121Snilay@cs.wisc.edu                if (bits(machInst, 23) == 1) {
51410121Snilay@cs.wisc.edu                    if (q) {
51510121Snilay@cs.wisc.edu                        return new Unknown(machInst);
5166657Snate@binkert.org                    } else {
5176657Snate@binkert.org                        return decodeNeonUSThreeUSReg<Vabdl>(
5186882SBrad.Beckmann@amd.com                                u, size, machInst, vd, vn, vm);
5196882SBrad.Beckmann@amd.com                    }
5206882SBrad.Beckmann@amd.com                } else {
52110121Snilay@cs.wisc.edu                    return decodeNeonUSThreeReg<VabdD, VabdQ>(
52210121Snilay@cs.wisc.edu                            q, u, size, machInst, vd, vn, vm);
5236882SBrad.Beckmann@amd.com                }
5246877Ssteve.reinhardt@amd.com            }
5256882SBrad.Beckmann@amd.com          case 0x8:
52610308Snilay@cs.wisc.edu            if (b) {
5276882SBrad.Beckmann@amd.com                if (u) {
52810308Snilay@cs.wisc.edu                    return decodeNeonUThreeReg<VceqD, VceqQ>(
52910311Snilay@cs.wisc.edu                            q, size, machInst, vd, vn, vm);
53010308Snilay@cs.wisc.edu                } else {
53110308Snilay@cs.wisc.edu                    return decodeNeonUThreeReg<VtstD, VtstQ>(
53210917Sbrandon.potter@amd.com                            q, size, machInst, vd, vn, vm);
5339595Snilay@cs.wisc.edu                }
5349745Snilay@cs.wisc.edu            } else {
5359745Snilay@cs.wisc.edu                if (u) {
5369745Snilay@cs.wisc.edu                    return decodeNeonUThreeReg<NVsubD, NVsubQ>(
5379745Snilay@cs.wisc.edu                            q, size, machInst, vd, vn, vm);
5389745Snilay@cs.wisc.edu                } else {
5399745Snilay@cs.wisc.edu                    return decodeNeonUThreeReg<NVaddD, NVaddQ>(
5409745Snilay@cs.wisc.edu                            q, size, machInst, vd, vn, vm);
5419745Snilay@cs.wisc.edu                }
5429745Snilay@cs.wisc.edu            }
5439745Snilay@cs.wisc.edu          case 0x9:
5449595Snilay@cs.wisc.edu            if (b) {
5456657Snate@binkert.org                if (u) {
5466657Snate@binkert.org                    return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
5476657Snate@binkert.org                            q, size, machInst, vd, vn, vm);
5486657Snate@binkert.org                } else {
5497007Snate@binkert.org                    return decodeNeonSThreeReg<NVmulD, NVmulQ>(
55011021Sjthestness@gmail.com                            q, size, machInst, vd, vn, vm);
55110311Snilay@cs.wisc.edu                }
55210311Snilay@cs.wisc.edu            } else {
55310311Snilay@cs.wisc.edu                if (u) {
55410311Snilay@cs.wisc.edu                    return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
55510311Snilay@cs.wisc.edu                            q, u, size, machInst, vd, vn, vm);
55610311Snilay@cs.wisc.edu                } else {
55710311Snilay@cs.wisc.edu                    return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
55810311Snilay@cs.wisc.edu                            q, u, size, machInst, vd, vn, vm);
55910311Snilay@cs.wisc.edu                }
56010311Snilay@cs.wisc.edu            }
56110311Snilay@cs.wisc.edu          case 0xa:
56210311Snilay@cs.wisc.edu            if (q)
56310311Snilay@cs.wisc.edu                return new Unknown(machInst);
56411084Snilay@cs.wisc.edu            if (b) {
56510311Snilay@cs.wisc.edu                return decodeNeonUSThreeUSReg<VpminD>(
56610311Snilay@cs.wisc.edu                        u, size, machInst, vd, vn, vm);
56711021Sjthestness@gmail.com            } else {
56811021Sjthestness@gmail.com                return decodeNeonUSThreeUSReg<VpmaxD>(
56910311Snilay@cs.wisc.edu                        u, size, machInst, vd, vn, vm);
57010311Snilay@cs.wisc.edu            }
57110311Snilay@cs.wisc.edu          case 0xb:
57210311Snilay@cs.wisc.edu            if (b) {
57310311Snilay@cs.wisc.edu                if (u || q) {
57410311Snilay@cs.wisc.edu                    return new Unknown(machInst);
57510311Snilay@cs.wisc.edu                } else {
57610311Snilay@cs.wisc.edu                    return decodeNeonUThreeUSReg<NVpaddD>(
57710311Snilay@cs.wisc.edu                            size, machInst, vd, vn, vm);
57810311Snilay@cs.wisc.edu                }
57910311Snilay@cs.wisc.edu            } else {
58011021Sjthestness@gmail.com                if (u) {
58111021Sjthestness@gmail.com                    return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
58210311Snilay@cs.wisc.edu                            q, size, machInst, vd, vn, vm);
58310311Snilay@cs.wisc.edu                } else {
58410311Snilay@cs.wisc.edu                    return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
58510311Snilay@cs.wisc.edu                            q, size, machInst, vd, vn, vm);
58610311Snilay@cs.wisc.edu                }
58710311Snilay@cs.wisc.edu            }
58810311Snilay@cs.wisc.edu          case 0xc:
58910311Snilay@cs.wisc.edu            if (b) {
59010311Snilay@cs.wisc.edu                if (!u) {
59110311Snilay@cs.wisc.edu                    if (bits(c, 1) == 0) {
5927007Snate@binkert.org                        if (q) {
5936657Snate@binkert.org                            return new NVfmaQFp<float>(machInst, vd, vn, vm);
5947007Snate@binkert.org                        } else {
59511021Sjthestness@gmail.com                            return new NVfmaDFp<float>(machInst, vd, vn, vm);
5966657Snate@binkert.org                        }
5976657Snate@binkert.org                    } else {
5986657Snate@binkert.org                        if (q) {
59910311Snilay@cs.wisc.edu                            return new NVfmsQFp<float>(machInst, vd, vn, vm);
6006657Snate@binkert.org                        } else {
6016657Snate@binkert.org                            return new NVfmsDFp<float>(machInst, vd, vn, vm);
60210305Snilay@cs.wisc.edu                        }
6036657Snate@binkert.org                    }
6046657Snate@binkert.org                }
6056657Snate@binkert.org            }
6066657Snate@binkert.org            return new Unknown(machInst);
6076657Snate@binkert.org          case 0xd:
6086657Snate@binkert.org            if (b) {
6096657Snate@binkert.org                if (u) {
6106657Snate@binkert.org                    if (bits(c, 1) == 0) {
61111084Snilay@cs.wisc.edu                        if (q) {
61211084Snilay@cs.wisc.edu                            return new NVmulQFp<float>(machInst, vd, vn, vm);
61311084Snilay@cs.wisc.edu                        } else {
61411084Snilay@cs.wisc.edu                            return new NVmulDFp<float>(machInst, vd, vn, vm);
61511084Snilay@cs.wisc.edu                        }
6166657Snate@binkert.org                    } else {
61711084Snilay@cs.wisc.edu                        return new Unknown(machInst);
6186657Snate@binkert.org                    }
6196657Snate@binkert.org                } else {
6206657Snate@binkert.org                    if (bits(c, 1) == 0) {
6217007Snate@binkert.org                        if (q) {
6226657Snate@binkert.org                            return new NVmlaQFp<float>(machInst, vd, vn, vm);
6237007Snate@binkert.org                        } else {
6247007Snate@binkert.org                            return new NVmlaDFp<float>(machInst, vd, vn, vm);
6256657Snate@binkert.org                        }
6269366Snilay@cs.wisc.edu                    } else {
6279366Snilay@cs.wisc.edu                        if (q) {
6289366Snilay@cs.wisc.edu                            return new NVmlsQFp<float>(machInst, vd, vn, vm);
6299366Snilay@cs.wisc.edu                        } else {
6307566SBrad.Beckmann@amd.com                            return new NVmlsDFp<float>(machInst, vd, vn, vm);
6317672Snate@binkert.org                        }
6326657Snate@binkert.org                    }
6339465Snilay@cs.wisc.edu                }
6346657Snate@binkert.org            } else {
6356657Snate@binkert.org                if (u) {
6366657Snate@binkert.org                    if (bits(c, 1) == 0) {
6377672Snate@binkert.org                        if (q) {
6386657Snate@binkert.org                            return new VpaddQFp<float>(machInst, vd, vn, vm);
6396657Snate@binkert.org                        } else {
6406657Snate@binkert.org                            return new VpaddDFp<float>(machInst, vd, vn, vm);
6416657Snate@binkert.org                        }
6426657Snate@binkert.org                    } else {
6436657Snate@binkert.org                        if (q) {
6446657Snate@binkert.org                            return new VabdQFp<float>(machInst, vd, vn, vm);
6456657Snate@binkert.org                        } else {
6466657Snate@binkert.org                            return new VabdDFp<float>(machInst, vd, vn, vm);
6476657Snate@binkert.org                        }
6486657Snate@binkert.org                    }
6499745Snilay@cs.wisc.edu                } else {
6506657Snate@binkert.org                    if (bits(c, 1) == 0) {
6516657Snate@binkert.org                        if (q) {
6529496Snilay@cs.wisc.edu                            return new VaddQFp<float>(machInst, vd, vn, vm);
6539496Snilay@cs.wisc.edu                        } else {
65410012Snilay@cs.wisc.edu                            return new VaddDFp<float>(machInst, vd, vn, vm);
6559496Snilay@cs.wisc.edu                        }
6569496Snilay@cs.wisc.edu                    } else {
6576657Snate@binkert.org                        if (q) {
65810121Snilay@cs.wisc.edu                            return new VsubQFp<float>(machInst, vd, vn, vm);
6596657Snate@binkert.org                        } else {
6606657Snate@binkert.org                            return new VsubDFp<float>(machInst, vd, vn, vm);
66110305Snilay@cs.wisc.edu                        }
6626657Snate@binkert.org                    }
66311021Sjthestness@gmail.com                }
66411021Sjthestness@gmail.com            }
66511021Sjthestness@gmail.com          case 0xe:
66611021Sjthestness@gmail.com            if (b) {
66711021Sjthestness@gmail.com                if (u) {
6688683Snilay@cs.wisc.edu                    if (bits(c, 1) == 0) {
6698683Snilay@cs.wisc.edu                        if (q) {
67010308Snilay@cs.wisc.edu                            return new VacgeQFp<float>(machInst, vd, vn, vm);
6718683Snilay@cs.wisc.edu                        } else {
67210308Snilay@cs.wisc.edu                            return new VacgeDFp<float>(machInst, vd, vn, vm);
6738683Snilay@cs.wisc.edu                        }
6746657Snate@binkert.org                    } else {
6759745Snilay@cs.wisc.edu                        if (q) {
6769745Snilay@cs.wisc.edu                            return new VacgtQFp<float>(machInst, vd, vn, vm);
6779745Snilay@cs.wisc.edu                        } else {
6789745Snilay@cs.wisc.edu                            return new VacgtDFp<float>(machInst, vd, vn, vm);
67910012Snilay@cs.wisc.edu                        }
68010012Snilay@cs.wisc.edu                    }
6819745Snilay@cs.wisc.edu                } else {
6829745Snilay@cs.wisc.edu                    return new Unknown(machInst);
6839745Snilay@cs.wisc.edu                }
6849745Snilay@cs.wisc.edu            } else {
6859745Snilay@cs.wisc.edu                if (u) {
68610919Sbrandon.potter@amd.com                    if (bits(c, 1) == 0) {
68710012Snilay@cs.wisc.edu                        if (q) {
6889745Snilay@cs.wisc.edu                            return new VcgeQFp<float>(machInst, vd, vn, vm);
6899745Snilay@cs.wisc.edu                        } else {
6909745Snilay@cs.wisc.edu                            return new VcgeDFp<float>(machInst, vd, vn, vm);
6919745Snilay@cs.wisc.edu                        }
6929745Snilay@cs.wisc.edu                    } else {
6939745Snilay@cs.wisc.edu                        if (q) {
6949745Snilay@cs.wisc.edu                            return new VcgtQFp<float>(machInst, vd, vn, vm);
6959745Snilay@cs.wisc.edu                        } else {
6969745Snilay@cs.wisc.edu                            return new VcgtDFp<float>(machInst, vd, vn, vm);
6979745Snilay@cs.wisc.edu                        }
6989745Snilay@cs.wisc.edu                    }
6999745Snilay@cs.wisc.edu                } else {
7009745Snilay@cs.wisc.edu                    if (bits(c, 1) == 0) {
7019745Snilay@cs.wisc.edu                        if (q) {
7029745Snilay@cs.wisc.edu                            return new VceqQFp<float>(machInst, vd, vn, vm);
7039745Snilay@cs.wisc.edu                        } else {
70410919Sbrandon.potter@amd.com                            return new VceqDFp<float>(machInst, vd, vn, vm);
70510012Snilay@cs.wisc.edu                        }
7069745Snilay@cs.wisc.edu                    } else {
7079745Snilay@cs.wisc.edu                        return new Unknown(machInst);
7089745Snilay@cs.wisc.edu                    }
7099745Snilay@cs.wisc.edu                }
7109745Snilay@cs.wisc.edu            }
7119745Snilay@cs.wisc.edu          case 0xf:
7129745Snilay@cs.wisc.edu            if (b) {
7139745Snilay@cs.wisc.edu                if (u) {
7149745Snilay@cs.wisc.edu                    return new Unknown(machInst);
7159745Snilay@cs.wisc.edu                } else {
7169745Snilay@cs.wisc.edu                    if (bits(c, 1) == 0) {
7179745Snilay@cs.wisc.edu                        if (q) {
7189745Snilay@cs.wisc.edu                            return new VrecpsQFp<float>(machInst, vd, vn, vm);
7199745Snilay@cs.wisc.edu                        } else {
7209745Snilay@cs.wisc.edu                            return new VrecpsDFp<float>(machInst, vd, vn, vm);
7219745Snilay@cs.wisc.edu                        }
72210920Sbrandon.potter@amd.com                    } else {
7239745Snilay@cs.wisc.edu                        if (q) {
72410920Sbrandon.potter@amd.com                            return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
72510920Sbrandon.potter@amd.com                        } else {
7269745Snilay@cs.wisc.edu                            return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
7279745Snilay@cs.wisc.edu                        }
7289745Snilay@cs.wisc.edu                    }
7299745Snilay@cs.wisc.edu                }
7309745Snilay@cs.wisc.edu            } else {
7319745Snilay@cs.wisc.edu                if (u) {
7329745Snilay@cs.wisc.edu                    if (bits(c, 1) == 0) {
7339745Snilay@cs.wisc.edu                        if (q) {
7349745Snilay@cs.wisc.edu                            return new VpmaxQFp<float>(machInst, vd, vn, vm);
7359745Snilay@cs.wisc.edu                        } else {
7369745Snilay@cs.wisc.edu                            return new VpmaxDFp<float>(machInst, vd, vn, vm);
7379745Snilay@cs.wisc.edu                        }
73810920Sbrandon.potter@amd.com                    } else {
7399745Snilay@cs.wisc.edu                        if (q) {
74010920Sbrandon.potter@amd.com                            return new VpminQFp<float>(machInst, vd, vn, vm);
74110920Sbrandon.potter@amd.com                        } else {
7429745Snilay@cs.wisc.edu                            return new VpminDFp<float>(machInst, vd, vn, vm);
7439745Snilay@cs.wisc.edu                        }
7449745Snilay@cs.wisc.edu                    }
7459745Snilay@cs.wisc.edu                } else {
7469745Snilay@cs.wisc.edu                    if (bits(c, 1) == 0) {
7479745Snilay@cs.wisc.edu                        if (q) {
7489745Snilay@cs.wisc.edu                            return new VmaxQFp<float>(machInst, vd, vn, vm);
7499745Snilay@cs.wisc.edu                        } else {
7509745Snilay@cs.wisc.edu                            return new VmaxDFp<float>(machInst, vd, vn, vm);
7519745Snilay@cs.wisc.edu                        }
7529745Snilay@cs.wisc.edu                    } else {
7539745Snilay@cs.wisc.edu                        if (q) {
7549745Snilay@cs.wisc.edu                            return new VminQFp<float>(machInst, vd, vn, vm);
7559745Snilay@cs.wisc.edu                        } else {
7569745Snilay@cs.wisc.edu                            return new VminDFp<float>(machInst, vd, vn, vm);
7579745Snilay@cs.wisc.edu                        }
7589745Snilay@cs.wisc.edu                    }
7599745Snilay@cs.wisc.edu                }
7609745Snilay@cs.wisc.edu            }
7619745Snilay@cs.wisc.edu        }
7629745Snilay@cs.wisc.edu        return new Unknown(machInst);
76311061Snilay@cs.wisc.edu    }
7649745Snilay@cs.wisc.edu
7659745Snilay@cs.wisc.edu    static StaticInstPtr
7669745Snilay@cs.wisc.edu    decodeNeonOneRegModImm(ExtMachInst machInst)
7679745Snilay@cs.wisc.edu    {
7689745Snilay@cs.wisc.edu        const IntRegIndex vd =
7699745Snilay@cs.wisc.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
7709745Snilay@cs.wisc.edu                               (bits(machInst, 22) << 4)));
7719745Snilay@cs.wisc.edu        const bool q = bits(machInst, 6);
7729745Snilay@cs.wisc.edu        const bool op = bits(machInst, 5);
7739745Snilay@cs.wisc.edu        const uint8_t cmode = bits(machInst, 11, 8);
7749745Snilay@cs.wisc.edu        const uint8_t imm = ((THUMB ? bits(machInst, 28) :
77511061Snilay@cs.wisc.edu                                      bits(machInst, 24)) << 7) |
7769745Snilay@cs.wisc.edu                            (bits(machInst, 18, 16) << 4) |
7779745Snilay@cs.wisc.edu                            (bits(machInst, 3, 0) << 0);
7789745Snilay@cs.wisc.edu
7799745Snilay@cs.wisc.edu        // Check for invalid immediate encodings and return an unknown op
7809745Snilay@cs.wisc.edu        // if it happens
7819745Snilay@cs.wisc.edu        bool immValid = true;
7827007Snate@binkert.org        const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
7837007Snate@binkert.org        if (!immValid) {
7847007Snate@binkert.org            return new Unknown(machInst);
7856657Snate@binkert.org        }
7866657Snate@binkert.org
7876657Snate@binkert.org        if (op) {
7887007Snate@binkert.org            if (bits(cmode, 3) == 0) {
7897007Snate@binkert.org                if (bits(cmode, 0) == 0) {
7907007Snate@binkert.org                    if (q)
7916657Snate@binkert.org                        return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
7926657Snate@binkert.org                    else
7936657Snate@binkert.org                        return new NVmvniD<uint64_t>(machInst, vd, bigImm);
79411021Sjthestness@gmail.com                } else {
79511021Sjthestness@gmail.com                    if (q)
79611021Sjthestness@gmail.com                        return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
79711021Sjthestness@gmail.com                    else
79811021Sjthestness@gmail.com                        return new NVbiciD<uint64_t>(machInst, vd, bigImm);
79911021Sjthestness@gmail.com                }
8008683Snilay@cs.wisc.edu            } else {
8018683Snilay@cs.wisc.edu                if (bits(cmode, 2) == 1) {
8028683Snilay@cs.wisc.edu                    switch (bits(cmode, 1, 0)) {
8038683Snilay@cs.wisc.edu                      case 0:
8048683Snilay@cs.wisc.edu                      case 1:
8058683Snilay@cs.wisc.edu                        if (q)
8067007Snate@binkert.org                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
8077007Snate@binkert.org                        else
8087007Snate@binkert.org                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
8097007Snate@binkert.org                      case 2:
8107007Snate@binkert.org                        if (q)
8116657Snate@binkert.org                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
81210012Snilay@cs.wisc.edu                        else
8139745Snilay@cs.wisc.edu                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8149745Snilay@cs.wisc.edu                      case 3:
8159745Snilay@cs.wisc.edu                        if (q)
8169745Snilay@cs.wisc.edu                            return new Unknown(machInst);
8179745Snilay@cs.wisc.edu                        else
8189745Snilay@cs.wisc.edu                            return new Unknown(machInst);
8196902SBrad.Beckmann@amd.com                    }
8209745Snilay@cs.wisc.edu                } else {
8219745Snilay@cs.wisc.edu                    if (bits(cmode, 0) == 0) {
8229745Snilay@cs.wisc.edu                        if (q)
8239745Snilay@cs.wisc.edu                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
82410012Snilay@cs.wisc.edu                        else
8256902SBrad.Beckmann@amd.com                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
8267839Snilay@cs.wisc.edu                    } else {
8277839Snilay@cs.wisc.edu                        if (q)
8287839Snilay@cs.wisc.edu                            return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
8297839Snilay@cs.wisc.edu                        else
8307839Snilay@cs.wisc.edu                            return new NVbiciD<uint64_t>(machInst, vd, bigImm);
8317839Snilay@cs.wisc.edu                    }
8327839Snilay@cs.wisc.edu                }
8337839Snilay@cs.wisc.edu            }
8347839Snilay@cs.wisc.edu        } else {
8357839Snilay@cs.wisc.edu            if (bits(cmode, 3) == 0) {
8367839Snilay@cs.wisc.edu                if (bits(cmode, 0) == 0) {
8377839Snilay@cs.wisc.edu                    if (q)
8387839Snilay@cs.wisc.edu                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8397839Snilay@cs.wisc.edu                    else
8407839Snilay@cs.wisc.edu                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8417839Snilay@cs.wisc.edu                } else {
8427839Snilay@cs.wisc.edu                    if (q)
8437839Snilay@cs.wisc.edu                        return new NVorriQ<uint64_t>(machInst, vd, bigImm);
8447839Snilay@cs.wisc.edu                    else
8457839Snilay@cs.wisc.edu                        return new NVorriD<uint64_t>(machInst, vd, bigImm);
8467839Snilay@cs.wisc.edu                }
8477839Snilay@cs.wisc.edu            } else {
8487839Snilay@cs.wisc.edu                if (bits(cmode, 2) == 1) {
8497839Snilay@cs.wisc.edu                    if (q)
8507839Snilay@cs.wisc.edu                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8517839Snilay@cs.wisc.edu                    else
8527839Snilay@cs.wisc.edu                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8537839Snilay@cs.wisc.edu                } else {
8547839Snilay@cs.wisc.edu                    if (bits(cmode, 0) == 0) {
8557839Snilay@cs.wisc.edu                        if (q)
8567839Snilay@cs.wisc.edu                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8577839Snilay@cs.wisc.edu                        else
8587839Snilay@cs.wisc.edu                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8597839Snilay@cs.wisc.edu                    } else {
8607839Snilay@cs.wisc.edu                        if (q)
8617839Snilay@cs.wisc.edu                            return new NVorriQ<uint64_t>(machInst, vd, bigImm);
8627839Snilay@cs.wisc.edu                        else
8636902SBrad.Beckmann@amd.com                            return new NVorriD<uint64_t>(machInst, vd, bigImm);
8648683Snilay@cs.wisc.edu                    }
8658683Snilay@cs.wisc.edu                }
8668683Snilay@cs.wisc.edu            }
8678683Snilay@cs.wisc.edu        }
8688683Snilay@cs.wisc.edu        return new Unknown(machInst);
8698683Snilay@cs.wisc.edu    }
8708683Snilay@cs.wisc.edu
8718683Snilay@cs.wisc.edu    static StaticInstPtr
8728683Snilay@cs.wisc.edu    decodeNeonTwoRegAndShift(ExtMachInst machInst)
8738683Snilay@cs.wisc.edu    {
8748683Snilay@cs.wisc.edu        const uint32_t a = bits(machInst, 11, 8);
8758683Snilay@cs.wisc.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
8768683Snilay@cs.wisc.edu        const bool b = bits(machInst, 6);
8778683Snilay@cs.wisc.edu        const bool l = bits(machInst, 7);
8788683Snilay@cs.wisc.edu        const IntRegIndex vd =
8798683Snilay@cs.wisc.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
8808683Snilay@cs.wisc.edu                               (bits(machInst, 22) << 4)));
8816657Snate@binkert.org        const IntRegIndex vm =
8826657Snate@binkert.org            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
8837839Snilay@cs.wisc.edu                               (bits(machInst, 5) << 4)));
8847839Snilay@cs.wisc.edu        unsigned imm6 = bits(machInst, 21, 16);
8857839Snilay@cs.wisc.edu        unsigned imm = ((l ? 1 : 0) << 6) | imm6;
8867839Snilay@cs.wisc.edu        unsigned size = 3;
8876657Snate@binkert.org        unsigned lShiftAmt = 0;
8887839Snilay@cs.wisc.edu        unsigned bitSel;
8897839Snilay@cs.wisc.edu        for (bitSel = 1 << 6; true; bitSel >>= 1) {
8907839Snilay@cs.wisc.edu            if (bitSel & imm)
89111025Snilay@cs.wisc.edu                break;
8927839Snilay@cs.wisc.edu            else if (!size)
8938055Sksewell@umich.edu                return new Unknown(machInst);
89410963Sdavid.hashe@amd.com            size--;
89510963Sdavid.hashe@amd.com        }
89610963Sdavid.hashe@amd.com        lShiftAmt = imm6 & ~bitSel;
89710963Sdavid.hashe@amd.com        unsigned rShiftAmt = 0;
89810963Sdavid.hashe@amd.com        if (a != 0xe && a != 0xf) {
89910963Sdavid.hashe@amd.com            if (size > 2)
90010963Sdavid.hashe@amd.com                rShiftAmt = 64 - imm6;
9017839Snilay@cs.wisc.edu            else
9026657Snate@binkert.org                rShiftAmt = 2 * (8 << size) - imm6;
9037839Snilay@cs.wisc.edu        }
9047839Snilay@cs.wisc.edu
9057839Snilay@cs.wisc.edu        switch (a) {
9067839Snilay@cs.wisc.edu          case 0x0:
9077839Snilay@cs.wisc.edu            return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
9087839Snilay@cs.wisc.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
9097839Snilay@cs.wisc.edu          case 0x1:
9107839Snilay@cs.wisc.edu            return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
9117839Snilay@cs.wisc.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
91211025Snilay@cs.wisc.edu          case 0x2:
9137839Snilay@cs.wisc.edu            return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
9148055Sksewell@umich.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
9157839Snilay@cs.wisc.edu          case 0x3:
9167839Snilay@cs.wisc.edu            return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
9177839Snilay@cs.wisc.edu                    b, u, size, machInst, vd, vm, rShiftAmt);
9187839Snilay@cs.wisc.edu          case 0x4:
9197839Snilay@cs.wisc.edu            if (u) {
9207839Snilay@cs.wisc.edu                return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
9217839Snilay@cs.wisc.edu                        b, size, machInst, vd, vm, rShiftAmt);
9227839Snilay@cs.wisc.edu            } else {
9237839Snilay@cs.wisc.edu                return new Unknown(machInst);
9247839Snilay@cs.wisc.edu            }
9257839Snilay@cs.wisc.edu          case 0x5:
9267839Snilay@cs.wisc.edu            if (u) {
92711025Snilay@cs.wisc.edu                return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
9287839Snilay@cs.wisc.edu                        b, size, machInst, vd, vm, lShiftAmt);
9298055Sksewell@umich.edu            } else {
9307839Snilay@cs.wisc.edu                return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
9317839Snilay@cs.wisc.edu                        b, size, machInst, vd, vm, lShiftAmt);
9327839Snilay@cs.wisc.edu            }
9337839Snilay@cs.wisc.edu          case 0x6:
9347839Snilay@cs.wisc.edu          case 0x7:
9357839Snilay@cs.wisc.edu            if (u) {
9367839Snilay@cs.wisc.edu                if (a == 0x6) {
9377839Snilay@cs.wisc.edu                    return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
9387839Snilay@cs.wisc.edu                            b, size, machInst, vd, vm, lShiftAmt);
9397839Snilay@cs.wisc.edu                } else {
9406657Snate@binkert.org                    return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
9417007Snate@binkert.org                            b, size, machInst, vd, vm, lShiftAmt);
94211025Snilay@cs.wisc.edu                }
9436657Snate@binkert.org            } else {
9448055Sksewell@umich.edu                return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
9456657Snate@binkert.org                        b, size, machInst, vd, vm, lShiftAmt);
9466657Snate@binkert.org            }
9476657Snate@binkert.org          case 0x8:
9486657Snate@binkert.org            if (l) {
9498478Snilay@cs.wisc.edu                return new Unknown(machInst);
9508478Snilay@cs.wisc.edu            } else if (u) {
9518478Snilay@cs.wisc.edu                return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
9529302Snilay@cs.wisc.edu                        b, size, machInst, vd, vm, rShiftAmt);
9539302Snilay@cs.wisc.edu            } else {
95410524Snilay@cs.wisc.edu                return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
9559302Snilay@cs.wisc.edu                        b, size, machInst, vd, vm, rShiftAmt);
9569302Snilay@cs.wisc.edu            }
95710524Snilay@cs.wisc.edu          case 0x9:
9589302Snilay@cs.wisc.edu            if (l) {
9599302Snilay@cs.wisc.edu                return new Unknown(machInst);
9609302Snilay@cs.wisc.edu            } else if (u) {
9619302Snilay@cs.wisc.edu                return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
96210305Snilay@cs.wisc.edu                        b, size, machInst, vd, vm, rShiftAmt);
9639302Snilay@cs.wisc.edu            } else {
96410311Snilay@cs.wisc.edu                return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
96510311Snilay@cs.wisc.edu                        b, size, machInst, vd, vm, rShiftAmt);
96610311Snilay@cs.wisc.edu            }
96710311Snilay@cs.wisc.edu          case 0xa:
96810311Snilay@cs.wisc.edu            if (l || b) {
96910311Snilay@cs.wisc.edu                return new Unknown(machInst);
97010311Snilay@cs.wisc.edu            } else {
9719302Snilay@cs.wisc.edu                return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
9729302Snilay@cs.wisc.edu                        lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
9739302Snilay@cs.wisc.edu            }
9749302Snilay@cs.wisc.edu          case 0xe:
9759302Snilay@cs.wisc.edu            if (l) {
9766657Snate@binkert.org                return new Unknown(machInst);
9776657Snate@binkert.org            } else {
9789219Spower.jg@gmail.com                if (bits(imm6, 5) == 0)
9796657Snate@binkert.org                    return new Unknown(machInst);
9806657Snate@binkert.org                if (u) {
9816999Snate@binkert.org                    if (b) {
9826657Snate@binkert.org                        return new NVcvtu2fpQ<float>(
9836657Snate@binkert.org                                machInst, vd, vm, 64 - imm6);
9849104Shestness@cs.utexas.edu                    } else {
9859104Shestness@cs.utexas.edu                        return new NVcvtu2fpD<float>(
9869104Shestness@cs.utexas.edu                                machInst, vd, vm, 64 - imm6);
9879104Shestness@cs.utexas.edu                    }
9886657Snate@binkert.org                } else {
9896657Snate@binkert.org                    if (b) {
9906657Snate@binkert.org                        return new NVcvts2fpQ<float>(
9916657Snate@binkert.org                                machInst, vd, vm, 64 - imm6);
9928946Sandreas.hansson@arm.com                    } else {
9938946Sandreas.hansson@arm.com                        return new NVcvts2fpD<float>(
9948946Sandreas.hansson@arm.com                                machInst, vd, vm, 64 - imm6);
9957832Snate@binkert.org                    }
99610972Sdavid.hashe@amd.com                }
9977832Snate@binkert.org            }
9987007Snate@binkert.org          case 0xf:
99910972Sdavid.hashe@amd.com            if (l) {
100010972Sdavid.hashe@amd.com                return new Unknown(machInst);
100110972Sdavid.hashe@amd.com            } else {
100210972Sdavid.hashe@amd.com                if (bits(imm6, 5) == 0)
100310972Sdavid.hashe@amd.com                    return new Unknown(machInst);
10048229Snate@binkert.org                if (u) {
10058229Snate@binkert.org                    if (b) {
10068229Snate@binkert.org                        return new NVcvt2ufxQ<float>(
100710972Sdavid.hashe@amd.com                                machInst, vd, vm, 64 - imm6);
10089104Shestness@cs.utexas.edu                    } else {
10099104Shestness@cs.utexas.edu                        return new NVcvt2ufxD<float>(
10109104Shestness@cs.utexas.edu                                machInst, vd, vm, 64 - imm6);
10119104Shestness@cs.utexas.edu                    }
10129104Shestness@cs.utexas.edu                } else {
10139104Shestness@cs.utexas.edu                    if (b) {
10148229Snate@binkert.org                        return new NVcvt2sfxQ<float>(
101511108Sdavid.hashe@amd.com                                machInst, vd, vm, 64 - imm6);
101610972Sdavid.hashe@amd.com                    } else {
10179219Spower.jg@gmail.com                        return new NVcvt2sfxD<float>(
10189219Spower.jg@gmail.com                                machInst, vd, vm, 64 - imm6);
10199219Spower.jg@gmail.com                    }
10209219Spower.jg@gmail.com                }
10219219Spower.jg@gmail.com            }
10229219Spower.jg@gmail.com        }
102310963Sdavid.hashe@amd.com        return new Unknown(machInst);
102410963Sdavid.hashe@amd.com    }
10259219Spower.jg@gmail.com
10266657Snate@binkert.org    static StaticInstPtr
10277055Snate@binkert.org    decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
10287055Snate@binkert.org    {
10297007Snate@binkert.org        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
10307007Snate@binkert.org        const uint32_t a = bits(machInst, 11, 8);
10316657Snate@binkert.org        const IntRegIndex vd =
10326657Snate@binkert.org            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
10336657Snate@binkert.org                               (bits(machInst, 22) << 4)));
103410963Sdavid.hashe@amd.com        const IntRegIndex vn =
103510963Sdavid.hashe@amd.com            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
10366657Snate@binkert.org                               (bits(machInst, 7) << 4)));
10376657Snate@binkert.org        const IntRegIndex vm =
10386657Snate@binkert.org            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
10397007Snate@binkert.org                               (bits(machInst, 5) << 4)));
10409496Snilay@cs.wisc.edu        const unsigned size = bits(machInst, 21, 20);
10417007Snate@binkert.org        switch (a) {
10427007Snate@binkert.org          case 0x0:
10439499Snilay@cs.wisc.edu            return decodeNeonUSThreeUSReg<Vaddl>(
10446657Snate@binkert.org                    u, size, machInst, vd, vn, vm);
10456657Snate@binkert.org          case 0x1:
10466657Snate@binkert.org            return decodeNeonUSThreeUSReg<Vaddw>(
10476657Snate@binkert.org                    u, size, machInst, vd, vn, vm);
10486657Snate@binkert.org          case 0x2:
10496657Snate@binkert.org            return decodeNeonUSThreeUSReg<Vsubl>(
10506657Snate@binkert.org                    u, size, machInst, vd, vn, vm);
10516657Snate@binkert.org          case 0x3:
10526657Snate@binkert.org            return decodeNeonUSThreeUSReg<Vsubw>(
10536657Snate@binkert.org                    u, size, machInst, vd, vn, vm);
10546657Snate@binkert.org          case 0x4:
10556657Snate@binkert.org            if (u) {
10567567SBrad.Beckmann@amd.com                return decodeNeonUThreeUSReg<Vraddhn>(
10579996Snilay@cs.wisc.edu                        size, machInst, vd, vn, vm);
10587567SBrad.Beckmann@amd.com            } else {
10599996Snilay@cs.wisc.edu                return decodeNeonUThreeUSReg<Vaddhn>(
106010963Sdavid.hashe@amd.com                        size, machInst, vd, vn, vm);
106110963Sdavid.hashe@amd.com            }
106210963Sdavid.hashe@amd.com          case 0x5:
10636657Snate@binkert.org            return decodeNeonUSThreeUSReg<Vabal>(
106410963Sdavid.hashe@amd.com                    u, size, machInst, vd, vn, vm);
106510963Sdavid.hashe@amd.com          case 0x6:
106610963Sdavid.hashe@amd.com            if (u) {
106710963Sdavid.hashe@amd.com                return decodeNeonUThreeUSReg<Vrsubhn>(
106810963Sdavid.hashe@amd.com                        size, machInst, vd, vn, vm);
106910963Sdavid.hashe@amd.com            } else {
107010963Sdavid.hashe@amd.com                return decodeNeonUThreeUSReg<Vsubhn>(
107110963Sdavid.hashe@amd.com                        size, machInst, vd, vn, vm);
10726657Snate@binkert.org            }
10736657Snate@binkert.org          case 0x7:
10746657Snate@binkert.org            if (bits(machInst, 23)) {
10756657Snate@binkert.org                return decodeNeonUSThreeUSReg<Vabdl>(
10766657Snate@binkert.org                        u, size, machInst, vd, vn, vm);
10776657Snate@binkert.org            } else {
107810963Sdavid.hashe@amd.com                return decodeNeonUSThreeReg<VabdD, VabdQ>(
107910963Sdavid.hashe@amd.com                        bits(machInst, 6), u, size, machInst, vd, vn, vm);
108010963Sdavid.hashe@amd.com            }
108110963Sdavid.hashe@amd.com          case 0x8:
108210963Sdavid.hashe@amd.com            return decodeNeonUSThreeUSReg<Vmlal>(
108310963Sdavid.hashe@amd.com                    u, size, machInst, vd, vn, vm);
108410963Sdavid.hashe@amd.com          case 0xa:
108510963Sdavid.hashe@amd.com            return decodeNeonUSThreeUSReg<Vmlsl>(
108610963Sdavid.hashe@amd.com                    u, size, machInst, vd, vn, vm);
108710963Sdavid.hashe@amd.com          case 0x9:
108810963Sdavid.hashe@amd.com            if (u) {
108910963Sdavid.hashe@amd.com                return new Unknown(machInst);
109010963Sdavid.hashe@amd.com            } else {
109110963Sdavid.hashe@amd.com                return decodeNeonSThreeUSReg<Vqdmlal>(
109210963Sdavid.hashe@amd.com                        size, machInst, vd, vn, vm);
109310963Sdavid.hashe@amd.com            }
109410963Sdavid.hashe@amd.com          case 0xb:
109510963Sdavid.hashe@amd.com            if (u) {
109610963Sdavid.hashe@amd.com                return new Unknown(machInst);
10976657Snate@binkert.org            } else {
10986657Snate@binkert.org                return decodeNeonSThreeUSReg<Vqdmlsl>(
10996657Snate@binkert.org                        size, machInst, vd, vn, vm);
11006657Snate@binkert.org            }
11016657Snate@binkert.org          case 0xc:
11026657Snate@binkert.org            return decodeNeonUSThreeUSReg<Vmull>(
11036657Snate@binkert.org                    u, size, machInst, vd, vn, vm);
11046657Snate@binkert.org          case 0xd:
11056657Snate@binkert.org            if (u) {
11066999Snate@binkert.org                return new Unknown(machInst);
11076657Snate@binkert.org            } else {
11086657Snate@binkert.org                return decodeNeonSThreeUSReg<Vqdmull>(
11096657Snate@binkert.org                        size, machInst, vd, vn, vm);
11106657Snate@binkert.org            }
11116657Snate@binkert.org          case 0xe:
11126657Snate@binkert.org            return decodeNeonUThreeUSReg<Vmullp>(
11137832Snate@binkert.org                    size, machInst, vd, vn, vm);
11147832Snate@binkert.org        }
11157805Snilay@cs.wisc.edu        return new Unknown(machInst);
11167832Snate@binkert.org    }
11178232Snate@binkert.org
11188232Snate@binkert.org    static StaticInstPtr
11198229Snate@binkert.org    decodeNeonTwoRegScalar(ExtMachInst machInst)
11208229Snate@binkert.org    {
11218229Snate@binkert.org        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
11228229Snate@binkert.org        const uint32_t a = bits(machInst, 11, 8);
112311108Sdavid.hashe@amd.com        const unsigned size = bits(machInst, 21, 20);
11246657Snate@binkert.org        const IntRegIndex vd =
11256657Snate@binkert.org            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
11266657Snate@binkert.org                               (bits(machInst, 22) << 4)));
11276657Snate@binkert.org        const IntRegIndex vn =
11286657Snate@binkert.org            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
11296657Snate@binkert.org                               (bits(machInst, 7) << 4)));
11307007Snate@binkert.org        const IntRegIndex vm = (size == 2) ?
11317007Snate@binkert.org            (IntRegIndex)(2 * bits(machInst, 3, 0)) :
11327839Snilay@cs.wisc.edu            (IntRegIndex)(2 * bits(machInst, 2, 0));
11337839Snilay@cs.wisc.edu        const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
11347839Snilay@cs.wisc.edu            (bits(machInst, 3) | (bits(machInst, 5) << 1));
11357839Snilay@cs.wisc.edu        switch (a) {
11367839Snilay@cs.wisc.edu          case 0x0:
11377839Snilay@cs.wisc.edu            if (u) {
11387839Snilay@cs.wisc.edu                switch (size) {
11397839Snilay@cs.wisc.edu                  case 1:
11407839Snilay@cs.wisc.edu                    return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
11417839Snilay@cs.wisc.edu                  case 2:
114211025Snilay@cs.wisc.edu                    return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
11436657Snate@binkert.org                  default:
11447839Snilay@cs.wisc.edu                    return new Unknown(machInst);
114510305Snilay@cs.wisc.edu                }
114610305Snilay@cs.wisc.edu            } else {
11477839Snilay@cs.wisc.edu                switch (size) {
11488337Snilay@cs.wisc.edu                  case 1:
11497839Snilay@cs.wisc.edu                    return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
11508337Snilay@cs.wisc.edu                  case 2:
11517839Snilay@cs.wisc.edu                    return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
11528337Snilay@cs.wisc.edu                  default:
11537839Snilay@cs.wisc.edu                    return new Unknown(machInst);
11548337Snilay@cs.wisc.edu                }
11557839Snilay@cs.wisc.edu            }
11567839Snilay@cs.wisc.edu          case 0x1:
115710305Snilay@cs.wisc.edu            if (u)
11586657Snate@binkert.org                return new VmlasQFp<float>(machInst, vd, vn, vm, index);
115910305Snilay@cs.wisc.edu            else
116010305Snilay@cs.wisc.edu                return new VmlasDFp<float>(machInst, vd, vn, vm, index);
116110305Snilay@cs.wisc.edu          case 0x4:
11626657Snate@binkert.org            if (u) {
116310305Snilay@cs.wisc.edu                switch (size) {
11647839Snilay@cs.wisc.edu                  case 1:
11657839Snilay@cs.wisc.edu                    return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
11667839Snilay@cs.wisc.edu                  case 2:
11677839Snilay@cs.wisc.edu                    return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
11687839Snilay@cs.wisc.edu                  default:
11697839Snilay@cs.wisc.edu                    return new Unknown(machInst);
11707839Snilay@cs.wisc.edu                }
11717839Snilay@cs.wisc.edu            } else {
11727839Snilay@cs.wisc.edu                switch (size) {
11736657Snate@binkert.org                  case 1:
117411049Snilay@cs.wisc.edu                    return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
117511049Snilay@cs.wisc.edu                  case 2:
11767839Snilay@cs.wisc.edu                    return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
11776657Snate@binkert.org                  default:
117810305Snilay@cs.wisc.edu                    return new Unknown(machInst);
117910305Snilay@cs.wisc.edu                }
118010305Snilay@cs.wisc.edu            }
118110305Snilay@cs.wisc.edu          case 0x5:
118210305Snilay@cs.wisc.edu            if (u)
118311025Snilay@cs.wisc.edu                return new VmlssQFp<float>(machInst, vd, vn, vm, index);
118410305Snilay@cs.wisc.edu            else
118510305Snilay@cs.wisc.edu                return new VmlssDFp<float>(machInst, vd, vn, vm, index);
118610305Snilay@cs.wisc.edu          case 0x2:
118710305Snilay@cs.wisc.edu            if (u) {
118810305Snilay@cs.wisc.edu                switch (size) {
118910305Snilay@cs.wisc.edu                  case 1:
119010305Snilay@cs.wisc.edu                    return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
11917839Snilay@cs.wisc.edu                  case 2:
11927839Snilay@cs.wisc.edu                    return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
11938337Snilay@cs.wisc.edu                  default:
11948341Snilay@cs.wisc.edu                    return new Unknown(machInst);
11957839Snilay@cs.wisc.edu                }
11968337Snilay@cs.wisc.edu            } else {
11978341Snilay@cs.wisc.edu                switch (size) {
11987839Snilay@cs.wisc.edu                  case 1:
11998337Snilay@cs.wisc.edu                    return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
12008341Snilay@cs.wisc.edu                  case 2:
12017839Snilay@cs.wisc.edu                    return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
12028337Snilay@cs.wisc.edu                  default:
12038341Snilay@cs.wisc.edu                    return new Unknown(machInst);
12047839Snilay@cs.wisc.edu                }
12057839Snilay@cs.wisc.edu            }
120610305Snilay@cs.wisc.edu          case 0x6:
120711025Snilay@cs.wisc.edu            if (u) {
120810305Snilay@cs.wisc.edu                switch (size) {
120910305Snilay@cs.wisc.edu                  case 1:
121010305Snilay@cs.wisc.edu                    return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
121110305Snilay@cs.wisc.edu                  case 2:
121210305Snilay@cs.wisc.edu                    return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
121310305Snilay@cs.wisc.edu                  default:
121410305Snilay@cs.wisc.edu                    return new Unknown(machInst);
121511025Snilay@cs.wisc.edu                }
121610305Snilay@cs.wisc.edu            } else {
121710305Snilay@cs.wisc.edu                switch (size) {
121810305Snilay@cs.wisc.edu                  case 1:
121910305Snilay@cs.wisc.edu                    return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
122010305Snilay@cs.wisc.edu                  case 2:
122110305Snilay@cs.wisc.edu                    return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
12226657Snate@binkert.org                  default:
122310305Snilay@cs.wisc.edu                    return new Unknown(machInst);
122410305Snilay@cs.wisc.edu                }
122510305Snilay@cs.wisc.edu            }
122610305Snilay@cs.wisc.edu          case 0x3:
12276657Snate@binkert.org            if (u) {
12286657Snate@binkert.org                return new Unknown(machInst);
12297007Snate@binkert.org            } else {
12307007Snate@binkert.org                switch (size) {
12317007Snate@binkert.org                  case 1:
12327007Snate@binkert.org                    return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
12337839Snilay@cs.wisc.edu                  case 2:
12347839Snilay@cs.wisc.edu                    return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
12357839Snilay@cs.wisc.edu                  default:
12367839Snilay@cs.wisc.edu                    return new Unknown(machInst);
12377839Snilay@cs.wisc.edu                }
12387839Snilay@cs.wisc.edu            }
12397839Snilay@cs.wisc.edu          case 0x7:
12407839Snilay@cs.wisc.edu            if (u) {
12417839Snilay@cs.wisc.edu                return new Unknown(machInst);
12427839Snilay@cs.wisc.edu            } else {
12437839Snilay@cs.wisc.edu                switch (size) {
124411025Snilay@cs.wisc.edu                  case 1:
12456657Snate@binkert.org                    return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
12466657Snate@binkert.org                  case 2:
12476657Snate@binkert.org                    return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
12486657Snate@binkert.org                  default:
12496657Snate@binkert.org                    return new Unknown(machInst);
12506657Snate@binkert.org                }
12516657Snate@binkert.org            }
12526657Snate@binkert.org          case 0x8:
12536657Snate@binkert.org            if (u) {
12546657Snate@binkert.org                switch (size) {
12556657Snate@binkert.org                  case 1:
12566999Snate@binkert.org                    return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
12576657Snate@binkert.org                  case 2:
12586657Snate@binkert.org                    return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
125910964Sdavid.hashe@amd.com                  default:
126010964Sdavid.hashe@amd.com                    return new Unknown(machInst);
126110964Sdavid.hashe@amd.com                }
126210964Sdavid.hashe@amd.com            } else {
126310964Sdavid.hashe@amd.com                switch (size) {
126410964Sdavid.hashe@amd.com                  case 1:
126510964Sdavid.hashe@amd.com                    return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
126610964Sdavid.hashe@amd.com                  case 2:
126710964Sdavid.hashe@amd.com                    return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
126810964Sdavid.hashe@amd.com                  default:
126910964Sdavid.hashe@amd.com                    return new Unknown(machInst);
12706657Snate@binkert.org                }
12716657Snate@binkert.org            }
12729104Shestness@cs.utexas.edu          case 0x9:
12736657Snate@binkert.org            if (u)
12746657Snate@binkert.org                return new VmulsQFp<float>(machInst, vd, vn, vm, index);
12756657Snate@binkert.org            else
12766657Snate@binkert.org                return new VmulsDFp<float>(machInst, vd, vn, vm, index);
12776657Snate@binkert.org          case 0xa:
127810228Snilay@cs.wisc.edu            if (u) {
127911111Snilay@cs.wisc.edu                switch (size) {
12806657Snate@binkert.org                  case 1:
12816657Snate@binkert.org                    return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
12826657Snate@binkert.org                  case 2:
12836657Snate@binkert.org                    return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
12849105SBrad.Beckmann@amd.com                  default:
12859105SBrad.Beckmann@amd.com                    return new Unknown(machInst);
12869105SBrad.Beckmann@amd.com                }
12879105SBrad.Beckmann@amd.com            } else {
12889105SBrad.Beckmann@amd.com                switch (size) {
12899105SBrad.Beckmann@amd.com                  case 1:
12909105SBrad.Beckmann@amd.com                    return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
12919105SBrad.Beckmann@amd.com                  case 2:
12926657Snate@binkert.org                    return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
12936657Snate@binkert.org                  default:
12946657Snate@binkert.org                    return new Unknown(machInst);
12956657Snate@binkert.org                }
12966657Snate@binkert.org            }
12976657Snate@binkert.org          case 0xb:
12986657Snate@binkert.org            if (u) {
12999104Shestness@cs.utexas.edu                return new Unknown(machInst);
13009104Shestness@cs.utexas.edu            } else {
13019104Shestness@cs.utexas.edu                if (u) {
13029104Shestness@cs.utexas.edu                    switch (size) {
13036657Snate@binkert.org                      case 1:
13046657Snate@binkert.org                        return new Vqdmulls<uint16_t>(
13056657Snate@binkert.org                                machInst, vd, vn, vm, index);
13066657Snate@binkert.org                      case 2:
13076657Snate@binkert.org                        return new Vqdmulls<uint32_t>(
13086657Snate@binkert.org                                machInst, vd, vn, vm, index);
13096657Snate@binkert.org                      default:
13106657Snate@binkert.org                        return new Unknown(machInst);
13116657Snate@binkert.org                    }
13126657Snate@binkert.org                } else {
13137839Snilay@cs.wisc.edu                    switch (size) {
13147839Snilay@cs.wisc.edu                      case 1:
13157839Snilay@cs.wisc.edu                        return new Vqdmulls<int16_t>(
13167839Snilay@cs.wisc.edu                                machInst, vd, vn, vm, index);
13177839Snilay@cs.wisc.edu                      case 2:
13187839Snilay@cs.wisc.edu                        return new Vqdmulls<int32_t>(
13197839Snilay@cs.wisc.edu                                machInst, vd, vn, vm, index);
13207839Snilay@cs.wisc.edu                      default:
13217839Snilay@cs.wisc.edu                        return new Unknown(machInst);
13227839Snilay@cs.wisc.edu                    }
13237839Snilay@cs.wisc.edu                }
13247839Snilay@cs.wisc.edu            }
13256657Snate@binkert.org          case 0xc:
13266657Snate@binkert.org            if (u) {
13276657Snate@binkert.org                switch (size) {
13286657Snate@binkert.org                  case 1:
13296657Snate@binkert.org                    return new VqdmulhsQ<int16_t>(
13306657Snate@binkert.org                            machInst, vd, vn, vm, index);
13316657Snate@binkert.org                  case 2:
13326657Snate@binkert.org                    return new VqdmulhsQ<int32_t>(
13336657Snate@binkert.org                            machInst, vd, vn, vm, index);
13346657Snate@binkert.org                  default:
13356657Snate@binkert.org                    return new Unknown(machInst);
13366657Snate@binkert.org                }
13376657Snate@binkert.org            } else {
13386657Snate@binkert.org                switch (size) {
13396657Snate@binkert.org                  case 1:
13406657Snate@binkert.org                    return new VqdmulhsD<int16_t>(
13416657Snate@binkert.org                            machInst, vd, vn, vm, index);
134210305Snilay@cs.wisc.edu                  case 2:
13436657Snate@binkert.org                    return new VqdmulhsD<int32_t>(
13446657Snate@binkert.org                            machInst, vd, vn, vm, index);
13456657Snate@binkert.org                  default:
134610962SBrad.Beckmann@amd.com                    return new Unknown(machInst);
13478159SBrad.Beckmann@amd.com                }
13489465Snilay@cs.wisc.edu            }
13496657Snate@binkert.org          case 0xd:
135010305Snilay@cs.wisc.edu            if (u) {
13516657Snate@binkert.org                switch (size) {
13526657Snate@binkert.org                  case 1:
13536657Snate@binkert.org                    return new VqrdmulhsQ<int16_t>(
13546657Snate@binkert.org                            machInst, vd, vn, vm, index);
13556657Snate@binkert.org                  case 2:
13566657Snate@binkert.org                    return new VqrdmulhsQ<int32_t>(
13576657Snate@binkert.org                            machInst, vd, vn, vm, index);
13586657Snate@binkert.org                  default:
13596657Snate@binkert.org                    return new Unknown(machInst);
13607007Snate@binkert.org                }
13616999Snate@binkert.org            } else {
13627007Snate@binkert.org                switch (size) {
13637007Snate@binkert.org                  case 1:
13647007Snate@binkert.org                    return new VqrdmulhsD<int16_t>(
13657007Snate@binkert.org                            machInst, vd, vn, vm, index);
13667007Snate@binkert.org                  case 2:
13677007Snate@binkert.org                    return new VqrdmulhsD<int32_t>(
13686657Snate@binkert.org                            machInst, vd, vn, vm, index);
13696657Snate@binkert.org                  default:
13706657Snate@binkert.org                    return new Unknown(machInst);
13716657Snate@binkert.org                }
13726657Snate@binkert.org            }
13736657Snate@binkert.org        }
13746657Snate@binkert.org        return new Unknown(machInst);
13756657Snate@binkert.org    }
13766657Snate@binkert.org
13776657Snate@binkert.org    static StaticInstPtr
13786657Snate@binkert.org    decodeNeonTwoRegMisc(ExtMachInst machInst)
13796657Snate@binkert.org    {
13806657Snate@binkert.org        const uint32_t a = bits(machInst, 17, 16);
13816657Snate@binkert.org        const uint32_t b = bits(machInst, 10, 6);
13826657Snate@binkert.org        const bool q = bits(machInst, 6);
13836657Snate@binkert.org        const IntRegIndex vd =
13846657Snate@binkert.org            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
13856657Snate@binkert.org                               (bits(machInst, 22) << 4)));
13866657Snate@binkert.org        const IntRegIndex vm =
13876657Snate@binkert.org            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
13886657Snate@binkert.org                               (bits(machInst, 5) << 4)));
13896657Snate@binkert.org        const unsigned size = bits(machInst, 19, 18);
13906657Snate@binkert.org        switch (a) {
13916657Snate@binkert.org          case 0x0:
13926657Snate@binkert.org            switch (bits(b, 4, 1)) {
13936657Snate@binkert.org              case 0x0:
13946657Snate@binkert.org                switch (size) {
13956657Snate@binkert.org                  case 0:
13966657Snate@binkert.org                    if (q) {
13976999Snate@binkert.org                        return new NVrev64Q<uint8_t>(machInst, vd, vm);
13986657Snate@binkert.org                    } else {
13996657Snate@binkert.org                        return new NVrev64D<uint8_t>(machInst, vd, vm);
14007007Snate@binkert.org                    }
14017007Snate@binkert.org                  case 1:
14026657Snate@binkert.org                    if (q) {
14036657Snate@binkert.org                        return new NVrev64Q<uint16_t>(machInst, vd, vm);
14046657Snate@binkert.org                    } else {
14056657Snate@binkert.org                        return new NVrev64D<uint16_t>(machInst, vd, vm);
14066657Snate@binkert.org                    }
14076657Snate@binkert.org                  case 2:
14086657Snate@binkert.org                    if (q) {
14096657Snate@binkert.org                        return new NVrev64Q<uint32_t>(machInst, vd, vm);
14106657Snate@binkert.org                    } else {
14116657Snate@binkert.org                        return new NVrev64D<uint32_t>(machInst, vd, vm);
14126657Snate@binkert.org                    }
14136657Snate@binkert.org                  default:
14146657Snate@binkert.org                    return new Unknown(machInst);
14156657Snate@binkert.org                }
14166657Snate@binkert.org              case 0x1:
14176657Snate@binkert.org                switch (size) {
14186657Snate@binkert.org                  case 0:
14196657Snate@binkert.org                    if (q) {
14206657Snate@binkert.org                        return new NVrev32Q<uint8_t>(machInst, vd, vm);
14216657Snate@binkert.org                    } else {
14226657Snate@binkert.org                        return new NVrev32D<uint8_t>(machInst, vd, vm);
14236657Snate@binkert.org                    }
14246657Snate@binkert.org                  case 1:
14256657Snate@binkert.org                    if (q) {
14266657Snate@binkert.org                        return new NVrev32Q<uint16_t>(machInst, vd, vm);
14276657Snate@binkert.org                    } else {
14286657Snate@binkert.org                        return new NVrev32D<uint16_t>(machInst, vd, vm);
14296657Snate@binkert.org                    }
14306657Snate@binkert.org                  default:
14316657Snate@binkert.org                    return new Unknown(machInst);
14326657Snate@binkert.org                }
14336657Snate@binkert.org              case 0x2:
14346657Snate@binkert.org                if (size != 0) {
14356657Snate@binkert.org                    return new Unknown(machInst);
14366657Snate@binkert.org                } else if (q) {
14376657Snate@binkert.org                    return new NVrev16Q<uint8_t>(machInst, vd, vm);
14386657Snate@binkert.org                } else {
14396657Snate@binkert.org                    return new NVrev16D<uint8_t>(machInst, vd, vm);
14406657Snate@binkert.org                }
14416657Snate@binkert.org              case 0x4:
14426657Snate@binkert.org                return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
14436657Snate@binkert.org                        q, size, machInst, vd, vm);
14446657Snate@binkert.org              case 0x5:
14456657Snate@binkert.org                return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
14466657Snate@binkert.org                        q, size, machInst, vd, vm);
14476657Snate@binkert.org              case 0x8:
14486657Snate@binkert.org                return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
14496657Snate@binkert.org                        q, size, machInst, vd, vm);
14506657Snate@binkert.org              case 0x9:
14516657Snate@binkert.org                return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
14526657Snate@binkert.org                        q, size, machInst, vd, vm);
14536657Snate@binkert.org              case 0xa:
14546657Snate@binkert.org                return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
14556657Snate@binkert.org                        q, size, machInst, vd, vm);
14566657Snate@binkert.org              case 0xb:
14576657Snate@binkert.org                if (q)
14586657Snate@binkert.org                    return new NVmvnQ<uint64_t>(machInst, vd, vm);
14596657Snate@binkert.org                else
14606657Snate@binkert.org                    return new NVmvnD<uint64_t>(machInst, vd, vm);
14616657Snate@binkert.org              case 0xc:
14626657Snate@binkert.org                return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
14636657Snate@binkert.org                        q, size, machInst, vd, vm);
14646657Snate@binkert.org              case 0xd:
14656657Snate@binkert.org                return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
14666657Snate@binkert.org                        q, size, machInst, vd, vm);
14676657Snate@binkert.org              case 0xe:
14686657Snate@binkert.org                return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
14696657Snate@binkert.org                        q, size, machInst, vd, vm);
14706657Snate@binkert.org              case 0xf:
14716657Snate@binkert.org                return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
14726657Snate@binkert.org                        q, size, machInst, vd, vm);
14736657Snate@binkert.org              default:
14746657Snate@binkert.org                return new Unknown(machInst);
14756657Snate@binkert.org            }
14766657Snate@binkert.org          case 0x1:
14776657Snate@binkert.org            switch (bits(b, 3, 1)) {
14786657Snate@binkert.org              case 0x0:
14796657Snate@binkert.org                if (bits(b, 4)) {
14806657Snate@binkert.org                    if (q) {
14816657Snate@binkert.org                        return new NVcgtQFp<float>(machInst, vd, vm);
14826657Snate@binkert.org                    } else {
14836657Snate@binkert.org                        return new NVcgtDFp<float>(machInst, vd, vm);
14846657Snate@binkert.org                    }
14856657Snate@binkert.org                } else {
14866657Snate@binkert.org                    return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
14876657Snate@binkert.org                            q, size, machInst, vd, vm);
14886657Snate@binkert.org                }
14896657Snate@binkert.org              case 0x1:
14907007Snate@binkert.org                if (bits(b, 4)) {
14916657Snate@binkert.org                    if (q) {
14926657Snate@binkert.org                        return new NVcgeQFp<float>(machInst, vd, vm);
14936657Snate@binkert.org                    } else {
14946657Snate@binkert.org                        return new NVcgeDFp<float>(machInst, vd, vm);
14956657Snate@binkert.org                    }
14966657Snate@binkert.org                } else {
14976657Snate@binkert.org                    return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
14987007Snate@binkert.org                            q, size, machInst, vd, vm);
14996657Snate@binkert.org                }
15006657Snate@binkert.org              case 0x2:
15016657Snate@binkert.org                if (bits(b, 4)) {
15026657Snate@binkert.org                    if (q) {
15036657Snate@binkert.org                        return new NVceqQFp<float>(machInst, vd, vm);
15046657Snate@binkert.org                    } else {
15056657Snate@binkert.org                        return new NVceqDFp<float>(machInst, vd, vm);
15066657Snate@binkert.org                    }
15076657Snate@binkert.org                } else {
15086657Snate@binkert.org                    return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
15096657Snate@binkert.org                            q, size, machInst, vd, vm);
15106657Snate@binkert.org                }
15116657Snate@binkert.org              case 0x3:
15126657Snate@binkert.org                if (bits(b, 4)) {
15136657Snate@binkert.org                    if (q) {
151410917Sbrandon.potter@amd.com                        return new NVcleQFp<float>(machInst, vd, vm);
15156657Snate@binkert.org                    } else {
15166657Snate@binkert.org                        return new NVcleDFp<float>(machInst, vd, vm);
15176657Snate@binkert.org                    }
15186657Snate@binkert.org                } else {
15196657Snate@binkert.org                    return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
15206657Snate@binkert.org                            q, size, machInst, vd, vm);
15216657Snate@binkert.org                }
15226657Snate@binkert.org              case 0x4:
15236657Snate@binkert.org                if (bits(b, 4)) {
15246657Snate@binkert.org                    if (q) {
15256657Snate@binkert.org                        return new NVcltQFp<float>(machInst, vd, vm);
15266657Snate@binkert.org                    } else {
15276657Snate@binkert.org                        return new NVcltDFp<float>(machInst, vd, vm);
15286657Snate@binkert.org                    }
15296657Snate@binkert.org                } else {
15306657Snate@binkert.org                    return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
15316657Snate@binkert.org                            q, size, machInst, vd, vm);
15326657Snate@binkert.org                }
15336657Snate@binkert.org              case 0x6:
15346657Snate@binkert.org                if (bits(machInst, 10)) {
15356657Snate@binkert.org                    if (q)
15366657Snate@binkert.org                        return new NVabsQFp<float>(machInst, vd, vm);
1537                    else
1538                        return new NVabsDFp<float>(machInst, vd, vm);
1539                } else {
1540                    return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1541                            q, size, machInst, vd, vm);
1542                }
1543              case 0x7:
1544                if (bits(machInst, 10)) {
1545                    if (q)
1546                        return new NVnegQFp<float>(machInst, vd, vm);
1547                    else
1548                        return new NVnegDFp<float>(machInst, vd, vm);
1549                } else {
1550                    return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1551                            q, size, machInst, vd, vm);
1552                }
1553            }
1554          case 0x2:
1555            switch (bits(b, 4, 1)) {
1556              case 0x0:
1557                if (q)
1558                    return new NVswpQ<uint64_t>(machInst, vd, vm);
1559                else
1560                    return new NVswpD<uint64_t>(machInst, vd, vm);
1561              case 0x1:
1562                return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>(
1563                        q, size, machInst, vd, vm);
1564              case 0x2:
1565                return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1566                        q, size, machInst, vd, vm);
1567              case 0x3:
1568                return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1569                        q, size, machInst, vd, vm);
1570              case 0x4:
1571                if (b == 0x8) {
1572                    return decodeNeonUTwoMiscUSReg<NVmovn>(
1573                            size, machInst, vd, vm);
1574                } else {
1575                    return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1576                            size, machInst, vd, vm);
1577                }
1578              case 0x5:
1579                if (q) {
1580                    return decodeNeonUTwoMiscUSReg<NVqmovun>(
1581                            size, machInst, vd, vm);
1582                } else {
1583                    return decodeNeonSTwoMiscUSReg<NVqmovn>(
1584                            size, machInst, vd, vm);
1585                }
1586              case 0x6:
1587                if (b == 0xc) {
1588                    return decodeNeonSTwoShiftUSReg<NVshll>(
1589                            size, machInst, vd, vm, 8 << size);
1590                } else {
1591                    return new Unknown(machInst);
1592                }
1593              case 0xc:
1594              case 0xe:
1595                if (b == 0x18) {
1596                    if (size != 1 || (vm % 2))
1597                        return new Unknown(machInst);
1598                    return new NVcvts2h<uint16_t>(machInst, vd, vm);
1599                } else if (b == 0x1c) {
1600                    if (size != 1 || (vd % 2))
1601                        return new Unknown(machInst);
1602                    return new NVcvth2s<uint16_t>(machInst, vd, vm);
1603                } else {
1604                    return new Unknown(machInst);
1605                }
1606              default:
1607                return new Unknown(machInst);
1608            }
1609          case 0x3:
1610            if (bits(b, 4, 3) == 0x3) {
1611                if ((q && (vd % 2 || vm % 2)) || size != 2) {
1612                    return new Unknown(machInst);
1613                } else {
1614                    if (bits(b, 2)) {
1615                        if (bits(b, 1)) {
1616                            if (q) {
1617                                return new NVcvt2ufxQ<float>(
1618                                        machInst, vd, vm, 0);
1619                            } else {
1620                                return new NVcvt2ufxD<float>(
1621                                        machInst, vd, vm, 0);
1622                            }
1623                        } else {
1624                            if (q) {
1625                                return new NVcvt2sfxQ<float>(
1626                                        machInst, vd, vm, 0);
1627                            } else {
1628                                return new NVcvt2sfxD<float>(
1629                                        machInst, vd, vm, 0);
1630                            }
1631                        }
1632                    } else {
1633                        if (bits(b, 1)) {
1634                            if (q) {
1635                                return new NVcvtu2fpQ<float>(
1636                                        machInst, vd, vm, 0);
1637                            } else {
1638                                return new NVcvtu2fpD<float>(
1639                                        machInst, vd, vm, 0);
1640                            }
1641                        } else {
1642                            if (q) {
1643                                return new NVcvts2fpQ<float>(
1644                                        machInst, vd, vm, 0);
1645                            } else {
1646                                return new NVcvts2fpD<float>(
1647                                        machInst, vd, vm, 0);
1648                            }
1649                        }
1650                    }
1651                }
1652            } else if ((b & 0x1a) == 0x10) {
1653                if (bits(b, 2)) {
1654                    if (q) {
1655                        return new NVrecpeQFp<float>(machInst, vd, vm);
1656                    } else {
1657                        return new NVrecpeDFp<float>(machInst, vd, vm);
1658                    }
1659                } else {
1660                    if (q) {
1661                        return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1662                    } else {
1663                        return new NVrecpeD<uint32_t>(machInst, vd, vm);
1664                    }
1665                }
1666            } else if ((b & 0x1a) == 0x12) {
1667                if (bits(b, 2)) {
1668                    if (q) {
1669                        return new NVrsqrteQFp<float>(machInst, vd, vm);
1670                    } else {
1671                        return new NVrsqrteDFp<float>(machInst, vd, vm);
1672                    }
1673                } else {
1674                    if (q) {
1675                        return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1676                    } else {
1677                        return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1678                    }
1679                }
1680            } else {
1681                return new Unknown(machInst);
1682            }
1683        }
1684        return new Unknown(machInst);
1685    }
1686
1687    StaticInstPtr
1688    decodeNeonData(ExtMachInst machInst)
1689    {
1690        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1691        const uint32_t a = bits(machInst, 23, 19);
1692        const uint32_t b = bits(machInst, 11, 8);
1693        const uint32_t c = bits(machInst, 7, 4);
1694        if (bits(a, 4) == 0) {
1695            return decodeNeonThreeRegistersSameLength(machInst);
1696        } else if ((c & 0x9) == 1) {
1697            if ((a & 0x7) == 0) {
1698                return decodeNeonOneRegModImm(machInst);
1699            } else {
1700                return decodeNeonTwoRegAndShift(machInst);
1701            }
1702        } else if ((c & 0x9) == 9) {
1703            return decodeNeonTwoRegAndShift(machInst);
1704        } else if (bits(a, 2, 1) != 0x3) {
1705            if ((c & 0x5) == 0) {
1706                return decodeNeonThreeRegDiffLengths(machInst);
1707            } else if ((c & 0x5) == 4) {
1708                return decodeNeonTwoRegScalar(machInst);
1709            }
1710        } else if ((a & 0x16) == 0x16) {
1711            const IntRegIndex vd =
1712                (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1713                                   (bits(machInst, 22) << 4)));
1714            const IntRegIndex vn =
1715                (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1716                                   (bits(machInst, 7) << 4)));
1717            const IntRegIndex vm =
1718                (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1719                                   (bits(machInst, 5) << 4)));
1720            if (!u) {
1721                if (bits(c, 0) == 0) {
1722                    unsigned imm4 = bits(machInst, 11, 8);
1723                    bool q = bits(machInst, 6);
1724                    if (imm4 >= 16 && !q)
1725                        return new Unknown(machInst);
1726                    if (q) {
1727                        return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1728                    } else {
1729                        return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1730                    }
1731                }
1732            } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1733                return decodeNeonTwoRegMisc(machInst);
1734            } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1735                unsigned length = bits(machInst, 9, 8) + 1;
1736                if ((uint32_t)vn / 2 + length > 32)
1737                    return new Unknown(machInst);
1738                if (bits(machInst, 6) == 0) {
1739                    switch (length) {
1740                      case 1:
1741                        return new NVtbl1(machInst, vd, vn, vm);
1742                      case 2:
1743                        return new NVtbl2(machInst, vd, vn, vm);
1744                      case 3:
1745                        return new NVtbl3(machInst, vd, vn, vm);
1746                      case 4:
1747                        return new NVtbl4(machInst, vd, vn, vm);
1748                    }
1749                } else {
1750                    switch (length) {
1751                      case 1:
1752                        return new NVtbx1(machInst, vd, vn, vm);
1753                      case 2:
1754                        return new NVtbx2(machInst, vd, vn, vm);
1755                      case 3:
1756                        return new NVtbx3(machInst, vd, vn, vm);
1757                      case 4:
1758                        return new NVtbx4(machInst, vd, vn, vm);
1759                    }
1760                }
1761            } else if (b == 0xc && (c & 0x9) == 0) {
1762                unsigned imm4 = bits(machInst, 19, 16);
1763                if (bits(imm4, 2, 0) == 0)
1764                    return new Unknown(machInst);
1765                unsigned size = 0;
1766                while ((imm4 & 0x1) == 0) {
1767                    size++;
1768                    imm4 >>= 1;
1769                }
1770                unsigned index = imm4 >> 1;
1771                const bool q = bits(machInst, 6);
1772                return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1773                        q, size, machInst, vd, vm, index);
1774            }
1775        }
1776        return new Unknown(machInst);
1777    }
1778    '''
1779}};
1780
1781def format ThumbNeonMem() {{
1782    decode_block = '''
1783    return decodeNeonMem(machInst);
1784    '''
1785}};
1786
1787def format ThumbNeonData() {{
1788    decode_block = '''
1789    return decodeNeonData(machInst);
1790    '''
1791}};
1792
1793let {{
1794    header_output = '''
1795    StaticInstPtr
1796    decodeExtensionRegLoadStore(ExtMachInst machInst);
1797    '''
1798    decoder_output = '''
1799    StaticInstPtr
1800    decodeExtensionRegLoadStore(ExtMachInst machInst)
1801    {
1802        const uint32_t opcode = bits(machInst, 24, 20);
1803        const uint32_t offset = bits(machInst, 7, 0);
1804        const bool single = (bits(machInst, 8) == 0);
1805        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1806        RegIndex vd;
1807        if (single) {
1808            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1809                                      bits(machInst, 22));
1810        } else {
1811            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1812                                      (bits(machInst, 22) << 5));
1813        }
1814        switch (bits(opcode, 4, 3)) {
1815          case 0x0:
1816            if (bits(opcode, 4, 1) == 0x2 &&
1817                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1818                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1819                if ((bits(machInst, 7, 4) & 0xd) != 1) {
1820                    break;
1821                }
1822                const IntRegIndex rt =
1823                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1824                const IntRegIndex rt2 =
1825                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1826                const bool op = bits(machInst, 20);
1827                uint32_t vm;
1828                if (single) {
1829                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1830                } else {
1831                    vm = (bits(machInst, 3, 0) << 1) |
1832                         (bits(machInst, 5) << 5);
1833                }
1834                if (op) {
1835                    return new Vmov2Core2Reg(machInst, rt, rt2,
1836                                             (IntRegIndex)vm);
1837                } else {
1838                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1839                                             rt, rt2);
1840                }
1841            }
1842            break;
1843          case 0x1:
1844            {
1845                if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) {
1846                    break;
1847                }
1848                switch (bits(opcode, 1, 0)) {
1849                  case 0x0:
1850                    return new VLdmStm(machInst, rn, vd, single,
1851                                       true, false, false, offset);
1852                  case 0x1:
1853                    return new VLdmStm(machInst, rn, vd, single,
1854                                       true, false, true, offset);
1855                  case 0x2:
1856                    return new VLdmStm(machInst, rn, vd, single,
1857                                       true, true, false, offset);
1858                  case 0x3:
1859                    // If rn == sp, then this is called vpop.
1860                    return new VLdmStm(machInst, rn, vd, single,
1861                                       true, true, true, offset);
1862                }
1863            }
1864          case 0x2:
1865            if (bits(opcode, 1, 0) == 0x2) {
1866                // If rn == sp, then this is called vpush.
1867                return new VLdmStm(machInst, rn, vd, single,
1868                                   false, true, false, offset);
1869            } else if (bits(opcode, 1, 0) == 0x3) {
1870                return new VLdmStm(machInst, rn, vd, single,
1871                                   false, true, true, offset);
1872            }
1873            // Fall through on purpose
1874          case 0x3:
1875            const bool up = (bits(machInst, 23) == 1);
1876            const uint32_t imm = bits(machInst, 7, 0) << 2;
1877            if (single) {
1878                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1879                                          (bits(machInst, 22)));
1880            } else {
1881                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1882                                          (bits(machInst, 22) << 5));
1883            }
1884            if (bits(opcode, 1, 0) == 0x0) {
1885                if (single) {
1886                    if (up) {
1887                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
1888                    } else {
1889                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
1890                    }
1891                } else {
1892                    if (up) {
1893                        return new %(vstr_ud)s(machInst, vd, vd + 1,
1894                                               rn, up, imm);
1895                    } else {
1896                        return new %(vstr_d)s(machInst, vd, vd + 1,
1897                                              rn, up, imm);
1898                    }
1899                }
1900            } else if (bits(opcode, 1, 0) == 0x1) {
1901                if (single) {
1902                    if (up) {
1903                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
1904                    } else {
1905                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
1906                    }
1907                } else {
1908                    if (up) {
1909                        return new %(vldr_ud)s(machInst, vd, vd + 1,
1910                                               rn, up, imm);
1911                    } else {
1912                        return new %(vldr_d)s(machInst, vd, vd + 1,
1913                                              rn, up, imm);
1914                    }
1915                }
1916            }
1917        }
1918        return new Unknown(machInst);
1919    }
1920    ''' % {
1921        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1922        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1923        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1924        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1925        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1926        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1927        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1928        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1929    }
1930}};
1931
1932def format ExtensionRegLoadStore() {{
1933    decode_block = '''
1934    return decodeExtensionRegLoadStore(machInst);
1935    '''
1936}};
1937
1938let {{
1939    header_output = '''
1940    StaticInstPtr
1941    decodeShortFpTransfer(ExtMachInst machInst);
1942    '''
1943    decoder_output = '''
1944    StaticInstPtr
1945    decodeShortFpTransfer(ExtMachInst machInst)
1946    {
1947        const uint32_t l = bits(machInst, 20);
1948        const uint32_t c = bits(machInst, 8);
1949        const uint32_t a = bits(machInst, 23, 21);
1950        const uint32_t b = bits(machInst, 6, 5);
1951        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1952            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
1953            // Determine if this is backported aarch64 FP instruction
1954            const bool b31_b24 = bits(machInst, 31, 24) == 0xFE;
1955            const bool b23 = bits(machInst, 23);
1956            const bool b21_b18 = bits(machInst, 21, 18) == 0xE;
1957            const bool b11_b9  = bits(machInst, 11, 9) == 0x5;
1958            const bool sz = bits(machInst, 8);
1959            const bool b7_b6   = bits(machInst, 7, 6) == 0x1;
1960            const bool b6 = bits(machInst, 6) == 0x0;
1961            const bool b4 = bits(machInst, 4) == 0x0;
1962            if (b31_b24 && b23 && b21_b18 && b11_b9 && b7_b6 && b4) {
1963                  // VINT* Integer Rounding Instructon
1964                  const uint32_t rm = bits(machInst, 17, 16);
1965
1966                  if (sz) {
1967                      const IntRegIndex vd =
1968                          (IntRegIndex)((bits(machInst, 22) << 5) |
1969                                        (bits(machInst, 15, 12) << 1));
1970                      const IntRegIndex vm =
1971                          (IntRegIndex)((bits(machInst, 5) << 5) |
1972                                        (bits(machInst, 3, 0) << 1));
1973                      switch(rm) {
1974                        case 0x0:
1975                          return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm,
1976                                                            true);
1977                        case 0x1:
1978                          return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm,
1979                                                            true);
1980                        case 0x2:
1981                          return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm,
1982                                                            true);
1983                        case 0x3:
1984                          return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm,
1985                                                            true);
1986                        default: return new Unknown(machInst);
1987                      }
1988                  } else {
1989                      const IntRegIndex vd =
1990                          (IntRegIndex)(bits(machInst, 22) |
1991                                       (bits(machInst, 15, 12) << 1));
1992                      const IntRegIndex vm =
1993                          (IntRegIndex)(bits(machInst, 5) |
1994                                        (bits(machInst, 3, 0) << 1));
1995                      switch(rm) {
1996                        case 0x0:
1997                          return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm,
1998                                                            false);
1999                        case 0x1:
2000                          return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm,
2001                                                            false);
2002                        case 0x2:
2003                          return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm,
2004                                                            false);
2005                        case 0x3:
2006                          return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm,
2007                                                            false);
2008                        default: return new Unknown(machInst);
2009                      }
2010                  }
2011            } else if (b31_b24 && !b23 && b11_b9 && b6 && b4){
2012                // VSEL* floating point conditional select
2013
2014                ConditionCode cond;
2015                switch(bits(machInst, 21, 20)) {
2016                  case 0x0: cond = COND_EQ; break;
2017                  case 0x1: cond = COND_VS; break;
2018                  case 0x2: cond = COND_GE; break;
2019                  case 0x3: cond = COND_GT; break;
2020                }
2021
2022                if (sz) {
2023                      const IntRegIndex vd =
2024                          (IntRegIndex)((bits(machInst, 22) << 5) |
2025                                        (bits(machInst, 15, 12) << 1));
2026                      const IntRegIndex vm =
2027                          (IntRegIndex)((bits(machInst, 5) << 5) |
2028                                        (bits(machInst, 3, 0) << 1));
2029                      const IntRegIndex vn =
2030                          (IntRegIndex)((bits(machInst, 7) << 5) |
2031                                       (bits(machInst, 19, 16) << 1));
2032                    return new VselD(machInst, vd, vn, vm, cond);
2033                } else {
2034                      const IntRegIndex vd =
2035                          (IntRegIndex)(bits(machInst, 22) |
2036                                       (bits(machInst, 15, 12) << 1));
2037                      const IntRegIndex vm =
2038                          (IntRegIndex)(bits(machInst, 5) |
2039                                        (bits(machInst, 3, 0) << 1));
2040                      const IntRegIndex vn =
2041                          (IntRegIndex)((bits(machInst, 19, 16) << 1) |
2042                                        bits(machInst, 7));
2043                      return new VselS(machInst, vd, vn, vm, cond);
2044                }
2045            } else {
2046                return new Unknown(machInst);
2047            }
2048        }
2049        if (l == 0 && c == 0) {
2050            if (a == 0) {
2051                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2052                                    bits(machInst, 7);
2053                const IntRegIndex rt =
2054                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2055                if (bits(machInst, 20) == 1) {
2056                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2057                } else {
2058                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2059                }
2060            } else if (a == 0x7) {
2061                const IntRegIndex rt =
2062                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2063                uint32_t reg = bits(machInst, 19, 16);
2064                uint32_t specReg;
2065                switch (reg) {
2066                  case 0:
2067                    specReg = MISCREG_FPSID;
2068                    break;
2069                  case 1:
2070                    specReg = MISCREG_FPSCR;
2071                    break;
2072                  case 6:
2073                    specReg = MISCREG_MVFR1;
2074                    break;
2075                  case 7:
2076                    specReg = MISCREG_MVFR0;
2077                    break;
2078                  case 8:
2079                    specReg = MISCREG_FPEXC;
2080                    break;
2081                  default:
2082                    return new Unknown(machInst);
2083                }
2084                if (specReg == MISCREG_FPSCR) {
2085                    return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
2086                } else {
2087                    uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt,
2088                        reg, a, bits(machInst, 7, 5));
2089                    return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss);
2090                }
2091            }
2092        } else if (l == 0 && c == 1) {
2093            if (bits(a, 2) == 0) {
2094                uint32_t vd = (bits(machInst, 7) << 5) |
2095                              (bits(machInst, 19, 16) << 1);
2096                // Handle accessing each single precision half of the vector.
2097                vd += bits(machInst, 21);
2098                const IntRegIndex rt =
2099                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2100                if (bits(machInst, 22) == 1) {
2101                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
2102                                            rt, bits(machInst, 6, 5));
2103                } else if (bits(machInst, 5) == 1) {
2104                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
2105                                            rt, bits(machInst, 6));
2106                } else if (bits(machInst, 6) == 0) {
2107                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
2108                } else {
2109                    return new Unknown(machInst);
2110                }
2111            } else if (bits(b, 1) == 0) {
2112                bool q = bits(machInst, 21);
2113                unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2114                IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2115                    (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2116                IntRegIndex rt = (IntRegIndex)(uint32_t)
2117                    bits(machInst, 15, 12);
2118                if (q) {
2119                    switch (be) {
2120                      case 0:
2121                        return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2122                      case 1:
2123                        return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2124                      case 2:
2125                        return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2126                      case 3:
2127                        return new Unknown(machInst);
2128                    }
2129                } else {
2130                    switch (be) {
2131                      case 0:
2132                        return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2133                      case 1:
2134                        return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2135                      case 2:
2136                        return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2137                      case 3:
2138                        return new Unknown(machInst);
2139                    }
2140                }
2141            }
2142        } else if (l == 1 && c == 0) {
2143            if (a == 0) {
2144                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2145                                    bits(machInst, 7);
2146                const IntRegIndex rt =
2147                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2148                if (bits(machInst, 20) == 1) {
2149                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2150                } else {
2151                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2152                }
2153            } else if (a == 7) {
2154                const IntRegIndex rt =
2155                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2156                uint32_t reg = bits(machInst, 19, 16);
2157                uint32_t specReg;
2158                switch (reg) {
2159                  case 0:
2160                    specReg = MISCREG_FPSID;
2161                    break;
2162                  case 1:
2163                    specReg = MISCREG_FPSCR;
2164                    break;
2165                  case 6:
2166                    specReg = MISCREG_MVFR1;
2167                    break;
2168                  case 7:
2169                    specReg = MISCREG_MVFR0;
2170                    break;
2171                  case 8:
2172                    specReg = MISCREG_FPEXC;
2173                    break;
2174                  default:
2175                    return new Unknown(machInst);
2176                }
2177                if (rt == 0xf) {
2178                    if (specReg == MISCREG_FPSCR) {
2179                        return new VmrsApsrFpscr(machInst);
2180                    } else {
2181                        return new Unknown(machInst);
2182                    }
2183                } else if (specReg == MISCREG_FPSCR) {
2184                    return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2185                } else {
2186                    uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt,
2187                        reg, a, bits(machInst, 7, 5));
2188                    return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss);
2189                }
2190            }
2191        } else {
2192            uint32_t vd = (bits(machInst, 7) << 5) |
2193                          (bits(machInst, 19, 16) << 1);
2194            // Handle indexing into each single precision half of the vector.
2195            vd += bits(machInst, 21);
2196            uint32_t index;
2197            const IntRegIndex rt =
2198                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2199            const bool u = (bits(machInst, 23) == 1);
2200            if (bits(machInst, 22) == 1) {
2201                index = bits(machInst, 6, 5);
2202                if (u) {
2203                    return new VmovRegCoreUB(machInst, rt,
2204                                             (IntRegIndex)vd, index);
2205                } else {
2206                    return new VmovRegCoreSB(machInst, rt,
2207                                             (IntRegIndex)vd, index);
2208                }
2209            } else if (bits(machInst, 5) == 1) {
2210                index = bits(machInst, 6);
2211                if (u) {
2212                    return new VmovRegCoreUH(machInst, rt,
2213                                             (IntRegIndex)vd, index);
2214                } else {
2215                    return new VmovRegCoreSH(machInst, rt,
2216                                             (IntRegIndex)vd, index);
2217                }
2218            } else if (bits(machInst, 6) == 0 && !u) {
2219                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2220            } else {
2221                return new Unknown(machInst);
2222            }
2223        }
2224        return new Unknown(machInst);
2225    }
2226    '''
2227}};
2228
2229def format ShortFpTransfer() {{
2230    decode_block = '''
2231    return decodeShortFpTransfer(machInst);
2232    '''
2233}};
2234
2235let {{
2236    header_output = '''
2237    StaticInstPtr
2238    decodeVfpData(ExtMachInst machInst);
2239    '''
2240    decoder_output = '''
2241    StaticInstPtr
2242    decodeVfpData(ExtMachInst machInst)
2243    {
2244        const uint32_t opc1 = bits(machInst, 23, 20);
2245        const uint32_t opc2 = bits(machInst, 19, 16);
2246        const uint32_t opc3 = bits(machInst, 7, 6);
2247        //const uint32_t opc4 = bits(machInst, 3, 0);
2248        const bool single = (bits(machInst, 8) == 0);
2249        // Used to select between vcmp and vcmpe.
2250        const bool e = (bits(machInst, 7) == 1);
2251        IntRegIndex vd;
2252        IntRegIndex vm;
2253        IntRegIndex vn;
2254        if (single) {
2255            vd = (IntRegIndex)(bits(machInst, 22) |
2256                    (bits(machInst, 15, 12) << 1));
2257            vm = (IntRegIndex)(bits(machInst, 5) |
2258                    (bits(machInst, 3, 0) << 1));
2259            vn = (IntRegIndex)(bits(machInst, 7) |
2260                    (bits(machInst, 19, 16) << 1));
2261        } else {
2262            vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2263                    (bits(machInst, 15, 12) << 1));
2264            vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2265                    (bits(machInst, 3, 0) << 1));
2266            vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2267                    (bits(machInst, 19, 16) << 1));
2268        }
2269        switch (opc1 & 0xb /* 1011 */) {
2270          case 0x0:
2271            if (bits(machInst, 6) == 0) {
2272                if (single) {
2273                    return decodeVfpRegRegRegOp<VmlaS>(
2274                            machInst, vd, vn, vm, false);
2275                } else {
2276                    return decodeVfpRegRegRegOp<VmlaD>(
2277                            machInst, vd, vn, vm, true);
2278                }
2279            } else {
2280                if (single) {
2281                    return decodeVfpRegRegRegOp<VmlsS>(
2282                            machInst, vd, vn, vm, false);
2283                } else {
2284                    return decodeVfpRegRegRegOp<VmlsD>(
2285                            machInst, vd, vn, vm, true);
2286                }
2287            }
2288          case 0x1:
2289            if (bits(machInst, 6) == 1) {
2290                if (single) {
2291                    return decodeVfpRegRegRegOp<VnmlaS>(
2292                            machInst, vd, vn, vm, false);
2293                } else {
2294                    return decodeVfpRegRegRegOp<VnmlaD>(
2295                            machInst, vd, vn, vm, true);
2296                }
2297            } else {
2298                if (single) {
2299                    return decodeVfpRegRegRegOp<VnmlsS>(
2300                            machInst, vd, vn, vm, false);
2301                } else {
2302                    return decodeVfpRegRegRegOp<VnmlsD>(
2303                            machInst, vd, vn, vm, true);
2304                }
2305            }
2306          case 0x2:
2307            if ((opc3 & 0x1) == 0) {
2308                if (single) {
2309                    return decodeVfpRegRegRegOp<VmulS>(
2310                            machInst, vd, vn, vm, false);
2311                } else {
2312                    return decodeVfpRegRegRegOp<VmulD>(
2313                            machInst, vd, vn, vm, true);
2314                }
2315            } else {
2316                if (single) {
2317                    return decodeVfpRegRegRegOp<VnmulS>(
2318                            machInst, vd, vn, vm, false);
2319                } else {
2320                    return decodeVfpRegRegRegOp<VnmulD>(
2321                            machInst, vd, vn, vm, true);
2322                }
2323            }
2324          case 0x3:
2325            if ((opc3 & 0x1) == 0) {
2326                if (single) {
2327                    return decodeVfpRegRegRegOp<VaddS>(
2328                            machInst, vd, vn, vm, false);
2329                } else {
2330                    return decodeVfpRegRegRegOp<VaddD>(
2331                            machInst, vd, vn, vm, true);
2332                }
2333            } else {
2334                if (single) {
2335                    return decodeVfpRegRegRegOp<VsubS>(
2336                            machInst, vd, vn, vm, false);
2337                } else {
2338                    return decodeVfpRegRegRegOp<VsubD>(
2339                            machInst, vd, vn, vm, true);
2340                }
2341            }
2342          case 0x8:
2343            if ((opc3 & 0x1) == 0) {
2344                if (single) {
2345                    return decodeVfpRegRegRegOp<VdivS>(
2346                            machInst, vd, vn, vm, false);
2347                } else {
2348                    return decodeVfpRegRegRegOp<VdivD>(
2349                            machInst, vd, vn, vm, true);
2350                }
2351            }
2352            break;
2353          case 0x9:
2354            if ((opc3 & 0x1) == 0) {
2355                if (single) {
2356                    return decodeVfpRegRegRegOp<VfnmaS>(
2357                            machInst, vd, vn, vm, false);
2358                } else {
2359                    return decodeVfpRegRegRegOp<VfnmaD>(
2360                            machInst, vd, vn, vm, true);
2361                }
2362            } else {
2363                if (single) {
2364                    return decodeVfpRegRegRegOp<VfnmsS>(
2365                            machInst, vd, vn, vm, false);
2366                } else {
2367                    return decodeVfpRegRegRegOp<VfnmsD>(
2368                            machInst, vd, vn, vm, true);
2369                }
2370            }
2371            break;
2372          case 0xa:
2373            if ((opc3 & 0x1) == 0) {
2374                if (single) {
2375                    return decodeVfpRegRegRegOp<VfmaS>(
2376                            machInst, vd, vn, vm, false);
2377                } else {
2378                    return decodeVfpRegRegRegOp<VfmaD>(
2379                            machInst, vd, vn, vm, true);
2380                }
2381            } else {
2382                if (single) {
2383                    return decodeVfpRegRegRegOp<VfmsS>(
2384                            machInst, vd, vn, vm, false);
2385                } else {
2386                    return decodeVfpRegRegRegOp<VfmsD>(
2387                            machInst, vd, vn, vm, true);
2388                }
2389            }
2390            break;
2391          case 0xb:
2392            if ((opc3 & 0x1) == 0) {
2393                const uint32_t baseImm =
2394                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2395                if (single) {
2396                    uint32_t imm = vfp_modified_imm(baseImm, false);
2397                    return decodeVfpRegImmOp<VmovImmS>(
2398                            machInst, vd, imm, false);
2399                } else {
2400                    uint64_t imm = vfp_modified_imm(baseImm, true);
2401                    return decodeVfpRegImmOp<VmovImmD>(
2402                            machInst, vd, imm, true);
2403                }
2404            }
2405            switch (opc2) {
2406              case 0x0:
2407                if (opc3 == 1) {
2408                    if (single) {
2409                        return decodeVfpRegRegOp<VmovRegS>(
2410                                machInst, vd, vm, false);
2411                    } else {
2412                        return decodeVfpRegRegOp<VmovRegD>(
2413                                machInst, vd, vm, true);
2414                    }
2415                } else {
2416                    if (single) {
2417                        return decodeVfpRegRegOp<VabsS>(
2418                                machInst, vd, vm, false);
2419                    } else {
2420                        return decodeVfpRegRegOp<VabsD>(
2421                                machInst, vd, vm, true);
2422                    }
2423                }
2424              case 0x1:
2425                if (opc3 == 1) {
2426                    if (single) {
2427                        return decodeVfpRegRegOp<VnegS>(
2428                                machInst, vd, vm, false);
2429                    } else {
2430                        return decodeVfpRegRegOp<VnegD>(
2431                                machInst, vd, vm, true);
2432                    }
2433                } else {
2434                    if (single) {
2435                        return decodeVfpRegRegOp<VsqrtS>(
2436                                machInst, vd, vm, false);
2437                    } else {
2438                        return decodeVfpRegRegOp<VsqrtD>(
2439                                machInst, vd, vm, true);
2440                    }
2441                }
2442              case 0x2:
2443              case 0x3:
2444                {
2445                    const bool toHalf = bits(machInst, 16);
2446                    const bool top = bits(machInst, 7);
2447                    if (top) {
2448                        if (toHalf) {
2449                            return new VcvtFpSFpHT(machInst, vd, vm);
2450                        } else {
2451                            return new VcvtFpHTFpS(machInst, vd, vm);
2452                        }
2453                    } else {
2454                        if (toHalf) {
2455                            return new VcvtFpSFpHB(machInst, vd, vm);
2456                        } else {
2457                            return new VcvtFpHBFpS(machInst, vd, vm);
2458                        }
2459                    }
2460                }
2461              case 0x4:
2462                if (single) {
2463                    if (e) {
2464                        return new VcmpeS(machInst, vd, vm);
2465                    } else {
2466                        return new VcmpS(machInst, vd, vm);
2467                    }
2468                } else {
2469                    if (e) {
2470                        return new VcmpeD(machInst, vd, vm);
2471                    } else {
2472                        return new VcmpD(machInst, vd, vm);
2473                    }
2474                }
2475              case 0x5:
2476                if (single) {
2477                    if (e) {
2478                        return new VcmpeZeroS(machInst, vd, 0);
2479                    } else {
2480                        return new VcmpZeroS(machInst, vd, 0);
2481                    }
2482                } else {
2483                    if (e) {
2484                        return new VcmpeZeroD(machInst, vd, 0);
2485                    } else {
2486                        return new VcmpZeroD(machInst, vd, 0);
2487                    }
2488                }
2489              case 0x7:
2490                if (opc3 == 0x3) {
2491                    if (single) {
2492                        vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2493                                (bits(machInst, 15, 12) << 1));
2494                        return new VcvtFpSFpD(machInst, vd, vm);
2495                    } else {
2496                        vd = (IntRegIndex)(bits(machInst, 22) |
2497                                (bits(machInst, 15, 12) << 1));
2498                        return new VcvtFpDFpS(machInst, vd, vm);
2499                    }
2500                }
2501                break;
2502              case 0x8:
2503                if (bits(machInst, 7) == 0) {
2504                    if (single) {
2505                        return new VcvtUIntFpS(machInst, vd, vm);
2506                    } else {
2507                        vm = (IntRegIndex)(bits(machInst, 5) |
2508                                (bits(machInst, 3, 0) << 1));
2509                        return new VcvtUIntFpD(machInst, vd, vm);
2510                    }
2511                } else {
2512                    if (single) {
2513                        return new VcvtSIntFpS(machInst, vd, vm);
2514                    } else {
2515                        vm = (IntRegIndex)(bits(machInst, 5) |
2516                                (bits(machInst, 3, 0) << 1));
2517                        return new VcvtSIntFpD(machInst, vd, vm);
2518                    }
2519                }
2520              case 0xa:
2521                {
2522                    const bool half = (bits(machInst, 7) == 0);
2523                    const uint32_t imm = bits(machInst, 5) |
2524                                         (bits(machInst, 3, 0) << 1);
2525                    const uint32_t size =
2526                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2527                    if (single) {
2528                        if (half) {
2529                            return new VcvtSHFixedFpS(machInst, vd, vd, size);
2530                        } else {
2531                            return new VcvtSFixedFpS(machInst, vd, vd, size);
2532                        }
2533                    } else {
2534                        if (half) {
2535                            return new VcvtSHFixedFpD(machInst, vd, vd, size);
2536                        } else {
2537                            return new VcvtSFixedFpD(machInst, vd, vd, size);
2538                        }
2539                    }
2540                }
2541              case 0xb:
2542                {
2543                    const bool half = (bits(machInst, 7) == 0);
2544                    const uint32_t imm = bits(machInst, 5) |
2545                                         (bits(machInst, 3, 0) << 1);
2546                    const uint32_t size =
2547                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2548                    if (single) {
2549                        if (half) {
2550                            return new VcvtUHFixedFpS(machInst, vd, vd, size);
2551                        } else {
2552                            return new VcvtUFixedFpS(machInst, vd, vd, size);
2553                        }
2554                    } else {
2555                        if (half) {
2556                            return new VcvtUHFixedFpD(machInst, vd, vd, size);
2557                        } else {
2558                            return new VcvtUFixedFpD(machInst, vd, vd, size);
2559                        }
2560                    }
2561                }
2562              case 0xc:
2563                if (bits(machInst, 7) == 0) {
2564                    if (single) {
2565                        return new VcvtFpUIntSR(machInst, vd, vm);
2566                    } else {
2567                        vd = (IntRegIndex)(bits(machInst, 22) |
2568                                (bits(machInst, 15, 12) << 1));
2569                        return new VcvtFpUIntDR(machInst, vd, vm);
2570                    }
2571                } else {
2572                    if (single) {
2573                        return new VcvtFpUIntS(machInst, vd, vm);
2574                    } else {
2575                        vd = (IntRegIndex)(bits(machInst, 22) |
2576                                (bits(machInst, 15, 12) << 1));
2577                        return new VcvtFpUIntD(machInst, vd, vm);
2578                    }
2579                }
2580              case 0xd:
2581                if (bits(machInst, 7) == 0) {
2582                    if (single) {
2583                        return new VcvtFpSIntSR(machInst, vd, vm);
2584                    } else {
2585                        vd = (IntRegIndex)(bits(machInst, 22) |
2586                                (bits(machInst, 15, 12) << 1));
2587                        return new VcvtFpSIntDR(machInst, vd, vm);
2588                    }
2589                } else {
2590                    if (single) {
2591                        return new VcvtFpSIntS(machInst, vd, vm);
2592                    } else {
2593                        vd = (IntRegIndex)(bits(machInst, 22) |
2594                                (bits(machInst, 15, 12) << 1));
2595                        return new VcvtFpSIntD(machInst, vd, vm);
2596                    }
2597                }
2598              case 0xe:
2599                {
2600                    const bool half = (bits(machInst, 7) == 0);
2601                    const uint32_t imm = bits(machInst, 5) |
2602                                         (bits(machInst, 3, 0) << 1);
2603                    const uint32_t size =
2604                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2605                    if (single) {
2606                        if (half) {
2607                            return new VcvtFpSHFixedS(machInst, vd, vd, size);
2608                        } else {
2609                            return new VcvtFpSFixedS(machInst, vd, vd, size);
2610                        }
2611                    } else {
2612                        if (half) {
2613                            return new VcvtFpSHFixedD(machInst, vd, vd, size);
2614                        } else {
2615                            return new VcvtFpSFixedD(machInst, vd, vd, size);
2616                        }
2617                    }
2618                }
2619              case 0xf:
2620                {
2621                    const bool half = (bits(machInst, 7) == 0);
2622                    const uint32_t imm = bits(machInst, 5) |
2623                                         (bits(machInst, 3, 0) << 1);
2624                    const uint32_t size =
2625                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2626                    if (single) {
2627                        if (half) {
2628                            return new VcvtFpUHFixedS(machInst, vd, vd, size);
2629                        } else {
2630                            return new VcvtFpUFixedS(machInst, vd, vd, size);
2631                        }
2632                    } else {
2633                        if (half) {
2634                            return new VcvtFpUHFixedD(machInst, vd, vd, size);
2635                        } else {
2636                            return new VcvtFpUFixedD(machInst, vd, vd, size);
2637                        }
2638                    }
2639                }
2640            }
2641            break;
2642        }
2643        return new Unknown(machInst);
2644    }
2645    '''
2646}};
2647
2648def format VfpData() {{
2649    decode_block = '''
2650    return decodeVfpData(machInst);
2651    '''
2652}};
2653