fp.isa revision 7643:775ccd204013
1360SN/A// -*- mode:c++ -*-
210850SGiacomo.Gabrielli@arm.com
310796Sbrandon.potter@amd.com// Copyright (c) 2010 ARM Limited
410027SChris.Adeniyi-Jones@arm.com// All rights reserved
510027SChris.Adeniyi-Jones@arm.com//
610027SChris.Adeniyi-Jones@arm.com// The license below extends only to copyright in the software and shall
710027SChris.Adeniyi-Jones@arm.com// not be construed as granting a license to any other intellectual
810027SChris.Adeniyi-Jones@arm.com// property including but not limited to intellectual property relating
910027SChris.Adeniyi-Jones@arm.com// to a hardware implementation of the functionality of the software
1010027SChris.Adeniyi-Jones@arm.com// licensed hereunder.  You may use the software subject to the license
1110027SChris.Adeniyi-Jones@arm.com// terms below provided that you ensure that this notice is replicated
1210027SChris.Adeniyi-Jones@arm.com// unmodified and in its entirety in all distributions of the software,
1310027SChris.Adeniyi-Jones@arm.com// modified or unmodified, in source code or in binary form.
1410027SChris.Adeniyi-Jones@arm.com//
151458SN/A// Copyright (c) 2007-2008 The Florida State University
16360SN/A// All rights reserved.
17360SN/A//
18360SN/A// Redistribution and use in source and binary forms, with or without
19360SN/A// modification, are permitted provided that the following conditions are
20360SN/A// met: redistributions of source code must retain the above copyright
21360SN/A// notice, this list of conditions and the following disclaimer;
22360SN/A// redistributions in binary form must reproduce the above copyright
23360SN/A// notice, this list of conditions and the following disclaimer in the
24360SN/A// documentation and/or other materials provided with the distribution;
25360SN/A// neither the name of the copyright holders nor the names of its
26360SN/A// contributors may be used to endorse or promote products derived from
27360SN/A// this software without specific prior written permission.
28360SN/A//
29360SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30360SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31360SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32360SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33360SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34360SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35360SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36360SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37360SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38360SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39360SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402665Ssaidi@eecs.umich.edu//
412665Ssaidi@eecs.umich.edu// Authors: Stephen Hines
422665Ssaidi@eecs.umich.edu
43360SN/A////////////////////////////////////////////////////////////////////
44360SN/A//
451354SN/A// Floating Point operate instructions
461354SN/A//
47360SN/A
482764Sstever@eecs.umich.eduoutput header {{
499202Spalle@lyckegaard.dk
509202Spalle@lyckegaard.dk    template<template <typename T> class Base>
512064SN/A    StaticInstPtr
52360SN/A    newNeonMemInst(const unsigned size,
53360SN/A                   const ExtMachInst &machInst,
54360SN/A                   const RegIndex dest, const RegIndex ra,
55360SN/A                   const uint32_t imm, const unsigned extraMemFlags)
56360SN/A    {
57360SN/A        switch (size) {
581809SN/A          case 0:
595543Ssaidi@eecs.umich.edu            return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags);
6011392Sbrandon.potter@amd.com          case 1:
611809SN/A            return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags);
6211392Sbrandon.potter@amd.com          case 2:
6311383Sbrandon.potter@amd.com            return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags);
643113Sgblack@eecs.umich.edu          case 3:
658229Snate@binkert.org            return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags);
668229Snate@binkert.org          default:
6711594Santhony.gutierrez@amd.com            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
687075Snate@binkert.org        }
698229Snate@binkert.org    }
707075Snate@binkert.org
71360SN/A    template<template <typename T> class Base>
722474SN/A    StaticInstPtr
735543Ssaidi@eecs.umich.edu    newNeonMixInst(const unsigned size,
7411392Sbrandon.potter@amd.com                   const ExtMachInst &machInst,
752462SN/A                   const RegIndex dest, const RegIndex op1,
761354SN/A                   const uint32_t step)
776216Snate@binkert.org    {
786658Snate@binkert.org        switch (size) {
792474SN/A          case 0:
802680Sktlim@umich.edu            return new Base<uint8_t>(machInst, dest, op1, step);
8111380Salexandru.dutu@amd.com          case 1:
828232Snate@binkert.org            return new Base<uint16_t>(machInst, dest, op1, step);
838229Snate@binkert.org          case 2:
847678Sgblack@eecs.umich.edu            return new Base<uint32_t>(machInst, dest, op1, step);
8510496Ssteve.reinhardt@amd.com          case 3:
868229Snate@binkert.org            return new Base<uint64_t>(machInst, dest, op1, step);
8710497Ssteve.reinhardt@amd.com          default:
888766Sgblack@eecs.umich.edu            panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
896640Svince@csl.cornell.edu        }
90360SN/A    }
9111380Salexandru.dutu@amd.com
9211380Salexandru.dutu@amd.com}};
9311380Salexandru.dutu@amd.com
9411380Salexandru.dutu@amd.comlet {{
9511380Salexandru.dutu@amd.com    header_output = '''
9611380Salexandru.dutu@amd.com    StaticInstPtr
9711380Salexandru.dutu@amd.com    decodeNeonMem(ExtMachInst machInst);
9811380Salexandru.dutu@amd.com
99360SN/A    StaticInstPtr
100360SN/A    decodeNeonData(ExtMachInst machInst);
101360SN/A    '''
102360SN/A
103360SN/A    decoder_output = '''
104360SN/A    StaticInstPtr
105360SN/A    decodeNeonMem(ExtMachInst machInst)
106378SN/A    {
1071450SN/A        const uint32_t b = bits(machInst, 11, 8);
1083114Sgblack@eecs.umich.edu        const bool single = bits(machInst, 23);
109360SN/A        const bool singleAll = single && (bits(b, 3, 2) == 3);
1105543Ssaidi@eecs.umich.edu        const bool load = bits(machInst, 21);
1115543Ssaidi@eecs.umich.edu
1125543Ssaidi@eecs.umich.edu        unsigned width = 0;
11310831Ssteve.reinhardt@amd.com
114360SN/A        if (single) {
115360SN/A            width = bits(b, 1, 0) + 1;
116360SN/A        } else {
117360SN/A            switch (bits(b, 3, 1)) {
118360SN/A              case 0x0: width = 4;
1192680Sktlim@umich.edu                break;
120360SN/A              case 0x1: width = (b & 0x1) ? 2 : 1;
12110831Ssteve.reinhardt@amd.com                break;
12210831Ssteve.reinhardt@amd.com              case 0x2: width = 3;
123360SN/A                break;
124360SN/A              case 0x3: width = 1;
125360SN/A                break;
126360SN/A              case 0x4: width = 2;
12710831Ssteve.reinhardt@amd.com                break;
128360SN/A              case 0x5:
129360SN/A                if ((b & 0x1) == 0) {
130360SN/A                    width = 1;
131360SN/A                    break;
1323114Sgblack@eecs.umich.edu                }
13310831Ssteve.reinhardt@amd.com                // Fall through on purpose.
13410831Ssteve.reinhardt@amd.com              default:
13510831Ssteve.reinhardt@amd.com                return new Unknown(machInst);
136360SN/A            }
137360SN/A        }
138360SN/A        assert(width > 0 && width <= 4);
139360SN/A
140360SN/A        const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0);
141360SN/A        const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16);
142360SN/A        const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) |
143360SN/A                                                 bits(machInst, 22) << 4);
144360SN/A        const uint32_t type = bits(machInst, 11, 8);
145360SN/A        uint32_t size = 0;
146360SN/A        uint32_t align = 0;
147360SN/A        unsigned inc = 1;
148378SN/A        unsigned regs = 1;
1491706SN/A        unsigned lane = 0;
1503114Sgblack@eecs.umich.edu        if (single) {
151378SN/A            if (singleAll) {
152378SN/A                size = bits(machInst, 7, 6);
153378SN/A                bool t = bits(machInst, 5);
154378SN/A                unsigned eBytes = (1 << size);
155378SN/A                align = (eBytes - 1) | TLB::AllowUnaligned;
1561706SN/A                if (width == 1) {
1573114Sgblack@eecs.umich.edu                    regs = t ? 2 : 1;
158360SN/A                    inc = 1;
1596109Ssanchezd@stanford.edu                } else {
1601706SN/A                    regs = width;
1613114Sgblack@eecs.umich.edu                    inc = t ? 2 : 1;
162378SN/A                }
1636109Ssanchezd@stanford.edu                switch (width) {
1646109Ssanchezd@stanford.edu                  case 1:
1656109Ssanchezd@stanford.edu                  case 2:
1666109Ssanchezd@stanford.edu                    if (bits(machInst, 4))
167378SN/A                        align = width * eBytes - 1;
1681706SN/A                    break;
1693114Sgblack@eecs.umich.edu                  case 3:
170378SN/A                    break;
1715748SSteve.Reinhardt@amd.com                  case 4:
1725748SSteve.Reinhardt@amd.com                    if (size == 3) {
1735748SSteve.Reinhardt@amd.com                        if (bits(machInst, 4) == 0)
174378SN/A                            return new Unknown(machInst);
175378SN/A                        size = 2;
1761706SN/A                        align = 0xf;
1773114Sgblack@eecs.umich.edu                    } else if (size == 2) {
178378SN/A                        if (bits(machInst, 4))
179378SN/A                            align = 7;
1801706SN/A                    } else {
1813114Sgblack@eecs.umich.edu                        if (bits(machInst, 4))
182378SN/A                            align = 4 * eBytes - 1;
183378SN/A                    }
1841706SN/A                    break;
1853114Sgblack@eecs.umich.edu                }
186378SN/A            } else {
187378SN/A                size = bits(machInst, 11, 10);
1881706SN/A                unsigned eBytes = (1 << size);
1893114Sgblack@eecs.umich.edu                align = (eBytes - 1) | TLB::AllowUnaligned;
190378SN/A                regs = width;
1914118Sgblack@eecs.umich.edu                unsigned indexAlign = bits(machInst, 7, 4);
1924118Sgblack@eecs.umich.edu                // If width is 1, inc is always 1. That's overridden later.
1934118Sgblack@eecs.umich.edu                switch (size) {
1944118Sgblack@eecs.umich.edu                  case 0:
195378SN/A                    inc = 1;
1961706SN/A                    lane = bits(indexAlign, 3, 1);
1973114Sgblack@eecs.umich.edu                    break;
198378SN/A                  case 1:
199378SN/A                    inc = bits(indexAlign, 1) ? 2 : 1;
2001706SN/A                    lane = bits(indexAlign, 3, 2);
2013114Sgblack@eecs.umich.edu                    break;
202360SN/A                  case 2:
2035513SMichael.Adler@intel.com                    inc = bits(indexAlign, 2) ? 2 : 1;
2045513SMichael.Adler@intel.com                    lane = bits(indexAlign, 3);
2055513SMichael.Adler@intel.com                    break;
2065513SMichael.Adler@intel.com                }
20710203SAli.Saidi@ARM.com                // Override inc for width of 1.
20810203SAli.Saidi@ARM.com                if (width == 1) {
20910203SAli.Saidi@ARM.com                    inc = 1;
21010203SAli.Saidi@ARM.com                }
2115513SMichael.Adler@intel.com                switch (width) {
2125513SMichael.Adler@intel.com                  case 1:
2135513SMichael.Adler@intel.com                    switch (size) {
214511SN/A                      case 0:
21510633Smichaelupton@gmail.com                        break;
21610633Smichaelupton@gmail.com                      case 1:
21710633Smichaelupton@gmail.com                        if (bits(indexAlign, 0))
2181706SN/A                            align = 1;
2193114Sgblack@eecs.umich.edu                        break;
220511SN/A                      case 2:
2215513SMichael.Adler@intel.com                        if (bits(indexAlign, 1, 0))
2225513SMichael.Adler@intel.com                            align = 3;
2235513SMichael.Adler@intel.com                        break;
2245513SMichael.Adler@intel.com                    }
225511SN/A                    break;
2261706SN/A                  case 2:
2273114Sgblack@eecs.umich.edu                    if (bits(indexAlign, 0))
2281706SN/A                        align = (2 * eBytes) - 1;
2291706SN/A                    break;
2301706SN/A                  case 3:
2311706SN/A                    break;
2323114Sgblack@eecs.umich.edu                  case 4:
2331706SN/A                    switch (size) {
2341706SN/A                      case 0:
2351706SN/A                      case 1:
2361706SN/A                        if (bits(indexAlign, 0))
2373114Sgblack@eecs.umich.edu                            align = (4 * eBytes) - 1;
2381706SN/A                        break;
239511SN/A                      case 2:
2406703Svince@csl.cornell.edu                        if (bits(indexAlign, 0))
2416703Svince@csl.cornell.edu                            align = (4 << bits(indexAlign, 1, 0)) - 1;
2426703Svince@csl.cornell.edu                        break;
2436703Svince@csl.cornell.edu                    }
2446685Stjones1@inf.ed.ac.uk                    break;
2456685Stjones1@inf.ed.ac.uk                }
2466685Stjones1@inf.ed.ac.uk            }
2476685Stjones1@inf.ed.ac.uk            if (size == 0x3) {
2486685Stjones1@inf.ed.ac.uk                return new Unknown(machInst);
2495513SMichael.Adler@intel.com            }
2505513SMichael.Adler@intel.com        } else {
2515513SMichael.Adler@intel.com            size = bits(machInst, 7, 6);
2525513SMichael.Adler@intel.com            align = bits(machInst, 5, 4);
2535513SMichael.Adler@intel.com            if (align == 0) {
2541999SN/A                // @align wasn't specified, so alignment can be turned off.
2551999SN/A                align = ((1 << size) - 1) | TLB::AllowUnaligned;
2563114Sgblack@eecs.umich.edu            } else {
2571999SN/A                align = ((4 << align) - 1);
2581999SN/A            }
2591999SN/A            switch (width) {
2601999SN/A              case 1:
2613114Sgblack@eecs.umich.edu                switch (type) {
2621999SN/A                  case 0x7: regs = 1;
2633079Sstever@eecs.umich.edu                    break;
2643079Sstever@eecs.umich.edu                  case 0xa: regs = 2;
2653114Sgblack@eecs.umich.edu                    break;
2663079Sstever@eecs.umich.edu                  case 0x6: regs = 3;
2672093SN/A                    break;
2682093SN/A                  case 0x2: regs = 4;
2693114Sgblack@eecs.umich.edu                    break;
2702093SN/A                  default:
2712687Sksewell@umich.edu                    return new Unknown(machInst);
2722687Sksewell@umich.edu                }
2733114Sgblack@eecs.umich.edu                break;
2742687Sksewell@umich.edu              case 2:
2752238SN/A                // Regs doesn't behave exactly as it does in the manual
2762238SN/A                // because they loop over regs registers twice and we break
2773114Sgblack@eecs.umich.edu                // it down in the macroop.
2782238SN/A                switch (type) {
2792238SN/A                  case 0x8: regs = 2; inc = 1;
2802238SN/A                    break;
2813114Sgblack@eecs.umich.edu                  case 0x9: regs = 2; inc = 2;
2822238SN/A                    break;
2832238SN/A                  case 0x3: regs = 4; inc = 2;
2842238SN/A                    break;
2853114Sgblack@eecs.umich.edu                  default:
2862238SN/A                    return new Unknown(machInst);
2872238SN/A                }
2882238SN/A                break;
2893114Sgblack@eecs.umich.edu              case 3:
2902238SN/A                regs = 3;
2912238SN/A                switch (type) {
2922238SN/A                  case 0x4: inc = 1;
2933114Sgblack@eecs.umich.edu                    break;
2942238SN/A                  case 0x5: inc = 2;;
2952238SN/A                    break;
2962238SN/A                  default:
2973114Sgblack@eecs.umich.edu                    return new Unknown(machInst);
2982238SN/A                }
2992238SN/A                break;
3002238SN/A              case 4:
3013114Sgblack@eecs.umich.edu                regs = 4;
3022238SN/A                switch (type) {
3036109Ssanchezd@stanford.edu                  case 0: inc = 1;
3046109Ssanchezd@stanford.edu                    break;
3056109Ssanchezd@stanford.edu                  case 1: inc = 2;
3062238SN/A                    break;
3079455Smitch.hayenga+gem5@gmail.com                  default:
3089455Smitch.hayenga+gem5@gmail.com                    return new Unknown(machInst);
3099455Smitch.hayenga+gem5@gmail.com                }
31010203SAli.Saidi@ARM.com                break;
31110203SAli.Saidi@ARM.com            }
31210203SAli.Saidi@ARM.com        }
3139455Smitch.hayenga+gem5@gmail.com
3149112Smarc.orr@gmail.com        if (load) {
3159112Smarc.orr@gmail.com            // Load instructions.
3169112Smarc.orr@gmail.com            if (single) {
3179112Smarc.orr@gmail.com                return new VldSingle(machInst, singleAll, width, rn, vd,
3189112Smarc.orr@gmail.com                                     regs, inc, size, align, rm, lane);
3199112Smarc.orr@gmail.com            } else {
3209112Smarc.orr@gmail.com                return new VldMult(machInst, width, rn, vd,
3219112Smarc.orr@gmail.com                                   regs, inc, size, align, rm);
3229112Smarc.orr@gmail.com            }
3239112Smarc.orr@gmail.com        } else {
3249112Smarc.orr@gmail.com            // Store instructions.
3259112Smarc.orr@gmail.com            if (single) {
3269112Smarc.orr@gmail.com                if (singleAll) {
3279112Smarc.orr@gmail.com                    return new Unknown(machInst);
3289112Smarc.orr@gmail.com                } else {
3299112Smarc.orr@gmail.com                    return new VstSingle(machInst, false, width, rn, vd,
3309112Smarc.orr@gmail.com                                         regs, inc, size, align, rm, lane);
3319112Smarc.orr@gmail.com                }
3329112Smarc.orr@gmail.com            } else {
3339112Smarc.orr@gmail.com                return new VstMult(machInst, width, rn, vd,
3349112Smarc.orr@gmail.com                                   regs, inc, size, align, rm);
3359112Smarc.orr@gmail.com            }
3369112Smarc.orr@gmail.com        }
3379112Smarc.orr@gmail.com        return new Unknown(machInst);
3389238Slluc.alvarez@bsc.es    }
3399112Smarc.orr@gmail.com    '''
3409112Smarc.orr@gmail.com
3419112Smarc.orr@gmail.com    decoder_output += '''
3429112Smarc.orr@gmail.com    static StaticInstPtr
3439112Smarc.orr@gmail.com    decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
3449112Smarc.orr@gmail.com    {
3459112Smarc.orr@gmail.com        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
3469112Smarc.orr@gmail.com        const uint32_t a = bits(machInst, 11, 8);
3479112Smarc.orr@gmail.com        const bool b = bits(machInst, 4);
3489112Smarc.orr@gmail.com        const uint32_t c = bits(machInst, 21, 20);
34911367Sandreas.hansson@arm.com        const IntRegIndex vd =
3509112Smarc.orr@gmail.com            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
35111321Ssteve.reinhardt@amd.com                               (bits(machInst, 22) << 4)));
3529112Smarc.orr@gmail.com        const IntRegIndex vn =
3539112Smarc.orr@gmail.com            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
3549112Smarc.orr@gmail.com                               (bits(machInst, 7) << 4)));
3559112Smarc.orr@gmail.com        const IntRegIndex vm =
3569112Smarc.orr@gmail.com            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
3579112Smarc.orr@gmail.com                               (bits(machInst, 5) << 4)));
3589112Smarc.orr@gmail.com        const unsigned size = bits(machInst, 21, 20);
3599112Smarc.orr@gmail.com        const bool q = bits(machInst, 6);
3609112Smarc.orr@gmail.com        if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1)))
3619112Smarc.orr@gmail.com            return new Unknown(machInst);
3629112Smarc.orr@gmail.com        switch (a) {
3639112Smarc.orr@gmail.com          case 0x0:
3649112Smarc.orr@gmail.com            if (b) {
3659112Smarc.orr@gmail.com                if (u) {
3669112Smarc.orr@gmail.com                    return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
3679112Smarc.orr@gmail.com                            q, size, machInst, vd, vn, vm);
3689112Smarc.orr@gmail.com                } else {
3699112Smarc.orr@gmail.com                    return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
3709112Smarc.orr@gmail.com                            q, size, machInst, vd, vn, vm);
3719112Smarc.orr@gmail.com                }
3729112Smarc.orr@gmail.com            } else {
3739112Smarc.orr@gmail.com                if (size == 3)
3749112Smarc.orr@gmail.com                    return new Unknown(machInst);
3759112Smarc.orr@gmail.com                return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
3769112Smarc.orr@gmail.com                        q, u, size, machInst, vd, vn, vm);
3779112Smarc.orr@gmail.com            }
3789112Smarc.orr@gmail.com          case 0x1:
3799112Smarc.orr@gmail.com            if (!b) {
3809112Smarc.orr@gmail.com                return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
38111321Ssteve.reinhardt@amd.com                        q, u, size, machInst, vd, vn, vm);
3829112Smarc.orr@gmail.com            } else {
3839112Smarc.orr@gmail.com                if (u) {
3849112Smarc.orr@gmail.com                    switch (c) {
3859112Smarc.orr@gmail.com                      case 0:
3869112Smarc.orr@gmail.com                        if (q) {
3879112Smarc.orr@gmail.com                            return new VeorQ<uint64_t>(machInst, vd, vn, vm);
3889112Smarc.orr@gmail.com                        } else {
3899112Smarc.orr@gmail.com                            return new VeorD<uint64_t>(machInst, vd, vn, vm);
3909238Slluc.alvarez@bsc.es                        }
3919112Smarc.orr@gmail.com                      case 1:
3929112Smarc.orr@gmail.com                        if (q) {
3939112Smarc.orr@gmail.com                            return new VbslQ<uint64_t>(machInst, vd, vn, vm);
3949112Smarc.orr@gmail.com                        } else {
3959112Smarc.orr@gmail.com                            return new VbslD<uint64_t>(machInst, vd, vn, vm);
3962238SN/A                        }
3972238SN/A                      case 2:
3982238SN/A                        if (q) {
3992238SN/A                            return new VbitQ<uint64_t>(machInst, vd, vn, vm);
4003114Sgblack@eecs.umich.edu                        } else {
4012238SN/A                            return new VbitD<uint64_t>(machInst, vd, vn, vm);
4022238SN/A                        }
4032238SN/A                      case 3:
4043114Sgblack@eecs.umich.edu                        if (q) {
4052238SN/A                            return new VbifQ<uint64_t>(machInst, vd, vn, vm);
4062238SN/A                        } else {
4072238SN/A                            return new VbifD<uint64_t>(machInst, vd, vn, vm);
4083114Sgblack@eecs.umich.edu                        }
4092238SN/A                    }
4102238SN/A                } else {
4112238SN/A                    switch (c) {
4123114Sgblack@eecs.umich.edu                      case 0:
4132238SN/A                        if (q) {
4142238SN/A                            return new VandQ<uint64_t>(machInst, vd, vn, vm);
4151354SN/A                        } else {
4161354SN/A                            return new VandD<uint64_t>(machInst, vd, vn, vm);
41710796Sbrandon.potter@amd.com                        }
41810796Sbrandon.potter@amd.com                      case 1:
4191354SN/A                        if (q) {
4201354SN/A                            return new VbicQ<uint64_t>(machInst, vd, vn, vm);
4211354SN/A                        } else {
4221354SN/A                            return new VbicD<uint64_t>(machInst, vd, vn, vm);
4231354SN/A                        }
4241354SN/A                      case 2:
4251354SN/A                        if (vn == vm) {
4261354SN/A                            if (q) {
4271354SN/A                                return new VmovQ<uint64_t>(
4281354SN/A                                        machInst, vd, vn, vm);
42910796Sbrandon.potter@amd.com                            } else {
4301354SN/A                                return new VmovD<uint64_t>(
43110796Sbrandon.potter@amd.com                                        machInst, vd, vn, vm);
4321354SN/A                            }
4331354SN/A                        } else {
4341354SN/A                            if (q) {
4351354SN/A                                return new VorrQ<uint64_t>(
43610796Sbrandon.potter@amd.com                                        machInst, vd, vn, vm);
43710796Sbrandon.potter@amd.com                            } else {
43810796Sbrandon.potter@amd.com                                return new VorrD<uint64_t>(
43910796Sbrandon.potter@amd.com                                        machInst, vd, vn, vm);
44010796Sbrandon.potter@amd.com                            }
44110796Sbrandon.potter@amd.com                        }
44210796Sbrandon.potter@amd.com                      case 3:
44310796Sbrandon.potter@amd.com                        if (q) {
44410796Sbrandon.potter@amd.com                            return new VornQ<uint64_t>(
44510796Sbrandon.potter@amd.com                                    machInst, vd, vn, vm);
44610796Sbrandon.potter@amd.com                        } else {
447360SN/A                            return new VornD<uint64_t>(
448360SN/A                                    machInst, vd, vn, vm);
449360SN/A                        }
450360SN/A                    }
451360SN/A                }
452360SN/A            }
453360SN/A          case 0x2:
4543113Sgblack@eecs.umich.edu            if (b) {
4553113Sgblack@eecs.umich.edu                if (u) {
4563113Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
4573113Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
4583113Sgblack@eecs.umich.edu                } else {
4593113Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
4603113Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
4613113Sgblack@eecs.umich.edu                }
4623113Sgblack@eecs.umich.edu            } else {
4633113Sgblack@eecs.umich.edu                if (size == 3)
4643113Sgblack@eecs.umich.edu                    return new Unknown(machInst);
4653113Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
4663113Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
4673113Sgblack@eecs.umich.edu            }
4683113Sgblack@eecs.umich.edu          case 0x3:
4693113Sgblack@eecs.umich.edu            if (b) {
4704189Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
4714189Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
4723113Sgblack@eecs.umich.edu            } else {
4733113Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
4743113Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
4753113Sgblack@eecs.umich.edu            }
4768737Skoansin.tan@gmail.com          case 0x4:
4773113Sgblack@eecs.umich.edu            if (b) {
4788737Skoansin.tan@gmail.com                if (u) {
4793277Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
4805515SMichael.Adler@intel.com                            q, size, machInst, vd, vm, vn);
4815515SMichael.Adler@intel.com                } else {
4825515SMichael.Adler@intel.com                    return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
4835515SMichael.Adler@intel.com                            q, size, machInst, vd, vm, vn);
4845515SMichael.Adler@intel.com                }
4858737Skoansin.tan@gmail.com            } else {
4863277Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VshlD, VshlQ>(
4878737Skoansin.tan@gmail.com                        q, u, size, machInst, vd, vm, vn);
4883277Sgblack@eecs.umich.edu            }
4898737Skoansin.tan@gmail.com          case 0x5:
4903277Sgblack@eecs.umich.edu            if (b) {
4918737Skoansin.tan@gmail.com                if (u) {
4923113Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
4933113Sgblack@eecs.umich.edu                            q, size, machInst, vd, vm, vn);
4943113Sgblack@eecs.umich.edu                } else {
4953113Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
4968737Skoansin.tan@gmail.com                            q, size, machInst, vd, vm, vn);
4973113Sgblack@eecs.umich.edu                }
4988737Skoansin.tan@gmail.com            } else {
4993114Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
5008737Skoansin.tan@gmail.com                        q, u, size, machInst, vd, vm, vn);
5013114Sgblack@eecs.umich.edu            }
5028737Skoansin.tan@gmail.com          case 0x6:
5033114Sgblack@eecs.umich.edu            if (b) {
5048737Skoansin.tan@gmail.com                return decodeNeonUSThreeReg<VminD, VminQ>(
5054061Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5064061Sgblack@eecs.umich.edu            } else {
5074061Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
5088737Skoansin.tan@gmail.com                        q, u, size, machInst, vd, vn, vm);
5093113Sgblack@eecs.umich.edu            }
5108737Skoansin.tan@gmail.com          case 0x7:
5113113Sgblack@eecs.umich.edu            if (b) {
5123113Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VabaD, VabaQ>(
5133113Sgblack@eecs.umich.edu                        q, u, size, machInst, vd, vn, vm);
5143113Sgblack@eecs.umich.edu            } else {
5153113Sgblack@eecs.umich.edu                if (bits(machInst, 23) == 1) {
5163113Sgblack@eecs.umich.edu                    if (q) {
5173113Sgblack@eecs.umich.edu                        return new Unknown(machInst);
5183113Sgblack@eecs.umich.edu                    } else {
5194189Sgblack@eecs.umich.edu                        return decodeNeonUSThreeUSReg<Vabdl>(
5204189Sgblack@eecs.umich.edu                                u, size, machInst, vd, vn, vm);
5213113Sgblack@eecs.umich.edu                    }
5223113Sgblack@eecs.umich.edu                } else {
5233113Sgblack@eecs.umich.edu                    return decodeNeonUSThreeReg<VabdD, VabdQ>(
5248737Skoansin.tan@gmail.com                            q, u, size, machInst, vd, vn, vm);
5253113Sgblack@eecs.umich.edu                }
5268737Skoansin.tan@gmail.com            }
5273113Sgblack@eecs.umich.edu          case 0x8:
5288737Skoansin.tan@gmail.com            if (b) {
5293113Sgblack@eecs.umich.edu                if (u) {
5303113Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VceqD, VceqQ>(
5313113Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5323113Sgblack@eecs.umich.edu                } else {
5333113Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<VtstD, VtstQ>(
5343113Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5353113Sgblack@eecs.umich.edu                }
5363113Sgblack@eecs.umich.edu            } else {
5373113Sgblack@eecs.umich.edu                if (u) {
5383113Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<NVsubD, NVsubQ>(
5398852Sandreas.hansson@arm.com                            q, size, machInst, vd, vn, vm);
5403113Sgblack@eecs.umich.edu                } else {
5413113Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<NVaddD, NVaddQ>(
5423113Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5433113Sgblack@eecs.umich.edu                }
5443113Sgblack@eecs.umich.edu            }
5453113Sgblack@eecs.umich.edu          case 0x9:
5463113Sgblack@eecs.umich.edu            if (b) {
5473113Sgblack@eecs.umich.edu                if (u) {
5483113Sgblack@eecs.umich.edu                    return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
5493113Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5508852Sandreas.hansson@arm.com                } else {
5513113Sgblack@eecs.umich.edu                    return decodeNeonSThreeReg<NVmulD, NVmulQ>(
5523113Sgblack@eecs.umich.edu                            q, size, machInst, vd, vn, vm);
5533113Sgblack@eecs.umich.edu                }
5543113Sgblack@eecs.umich.edu            } else {
5556686Stjones1@inf.ed.ac.uk                if (u) {
5563113Sgblack@eecs.umich.edu                    return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
5573113Sgblack@eecs.umich.edu                            q, u, size, machInst, vd, vn, vm);
5583113Sgblack@eecs.umich.edu                } else {
559378SN/A                    return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
560378SN/A                            q, u, size, machInst, vd, vn, vm);
5619141Smarc.orr@gmail.com                }
5629141Smarc.orr@gmail.com            }
563360SN/A          case 0xa:
5641450SN/A            if (b) {
5653114Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VpminD, VpminQ>(
5662680Sktlim@umich.edu                        q, u, size, machInst, vd, vn, vm);
567360SN/A            } else {
5686701Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>(
56910930Sbrandon.potter@amd.com                        q, u, size, machInst, vd, vn, vm);
5706701Sgblack@eecs.umich.edu            }
571360SN/A          case 0xb:
57210930Sbrandon.potter@amd.com            if (b) {
573360SN/A                if (u) {
57410932Sbrandon.potter@amd.com                    return new Unknown(machInst);
57510496Ssteve.reinhardt@amd.com                } else {
57610930Sbrandon.potter@amd.com                    return decodeNeonUThreeReg<NVpaddD, NVpaddQ>(
577360SN/A                            q, size, machInst, vd, vn, vm);
5781458SN/A                }
579360SN/A            } else {
580360SN/A                if (u) {
58110930Sbrandon.potter@amd.com                    return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
58210930Sbrandon.potter@amd.com                            q, size, machInst, vd, vn, vm);
58310496Ssteve.reinhardt@amd.com                } else {
58410496Ssteve.reinhardt@amd.com                    return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
5859141Smarc.orr@gmail.com                            q, size, machInst, vd, vn, vm);
5861458SN/A                }
5879141Smarc.orr@gmail.com            }
588360SN/A          case 0xc:
5899141Smarc.orr@gmail.com            return new Unknown(machInst);
59010930Sbrandon.potter@amd.com          case 0xd:
5919141Smarc.orr@gmail.com            if (b) {
592360SN/A                if (u) {
593360SN/A                    if (bits(c, 1) == 0) {
594360SN/A                        if (q) {
59510027SChris.Adeniyi-Jones@arm.com                            return new NVmulQFp<float>(machInst, vd, vn, vm);
5963114Sgblack@eecs.umich.edu                        } else {
59710027SChris.Adeniyi-Jones@arm.com                            return new NVmulDFp<float>(machInst, vd, vn, vm);
598360SN/A                        }
599360SN/A                    } else {
600360SN/A                        return new Unknown(machInst);
6018852Sandreas.hansson@arm.com                    }
6026701Sgblack@eecs.umich.edu                } else {
6031458SN/A                    if (bits(c, 1) == 0) {
604360SN/A                        if (q) {
6056701Sgblack@eecs.umich.edu                            return new NVmlaQFp<float>(machInst, vd, vn, vm);
6066701Sgblack@eecs.umich.edu                        } else {
607360SN/A                            return new NVmlaDFp<float>(machInst, vd, vn, vm);
608360SN/A                        }
609360SN/A                    } else {
610360SN/A                        if (q) {
611360SN/A                            return new NVmlsQFp<float>(machInst, vd, vn, vm);
612360SN/A                        } else {
613360SN/A                            return new NVmlsDFp<float>(machInst, vd, vn, vm);
614360SN/A                        }
615360SN/A                    }
616360SN/A                }
617360SN/A            } else {
618360SN/A                if (u) {
6191706SN/A                    if (bits(c, 1) == 0) {
620360SN/A                        if (q) {
621360SN/A                            return new VpaddQFp<float>(machInst, vd, vn, vm);
622360SN/A                        } else {
623360SN/A                            return new VpaddDFp<float>(machInst, vd, vn, vm);
624360SN/A                        }
6253669Sbinkertn@umich.edu                    } else {
6263669Sbinkertn@umich.edu                        if (q) {
6273669Sbinkertn@umich.edu                            return new VabdQFp<float>(machInst, vd, vn, vm);
6281706SN/A                        } else {
6291706SN/A                            return new VabdDFp<float>(machInst, vd, vn, vm);
63010496Ssteve.reinhardt@amd.com                        }
63110496Ssteve.reinhardt@amd.com                    }
63210496Ssteve.reinhardt@amd.com                } else {
63310496Ssteve.reinhardt@amd.com                    if (bits(c, 1) == 0) {
63410496Ssteve.reinhardt@amd.com                        if (q) {
63510496Ssteve.reinhardt@amd.com                            return new VaddQFp<float>(machInst, vd, vn, vm);
63610496Ssteve.reinhardt@amd.com                        } else {
63710496Ssteve.reinhardt@amd.com                            return new VaddDFp<float>(machInst, vd, vn, vm);
63810496Ssteve.reinhardt@amd.com                        }
63910496Ssteve.reinhardt@amd.com                    } else {
64010496Ssteve.reinhardt@amd.com                        if (q) {
64110496Ssteve.reinhardt@amd.com                            return new VsubQFp<float>(machInst, vd, vn, vm);
64210496Ssteve.reinhardt@amd.com                        } else {
64310496Ssteve.reinhardt@amd.com                            return new VsubDFp<float>(machInst, vd, vn, vm);
64410496Ssteve.reinhardt@amd.com                        }
64510496Ssteve.reinhardt@amd.com                    }
64610496Ssteve.reinhardt@amd.com                }
64710496Ssteve.reinhardt@amd.com            }
64810496Ssteve.reinhardt@amd.com          case 0xe:
64910496Ssteve.reinhardt@amd.com            if (b) {
6505795Ssaidi@eecs.umich.edu                if (u) {
6519143Ssteve.reinhardt@amd.com                    if (bits(c, 1) == 0) {
6529142Ssteve.reinhardt@amd.com                        if (q) {
6539142Ssteve.reinhardt@amd.com                            return new VacgeQFp<float>(machInst, vd, vn, vm);
6549143Ssteve.reinhardt@amd.com                        } else {
6555795Ssaidi@eecs.umich.edu                            return new VacgeDFp<float>(machInst, vd, vn, vm);
6569143Ssteve.reinhardt@amd.com                        }
6575795Ssaidi@eecs.umich.edu                    } else {
6585795Ssaidi@eecs.umich.edu                        if (q) {
6595795Ssaidi@eecs.umich.edu                            return new VacgtQFp<float>(machInst, vd, vn, vm);
6609143Ssteve.reinhardt@amd.com                        } else {
6615795Ssaidi@eecs.umich.edu                            return new VacgtDFp<float>(machInst, vd, vn, vm);
662360SN/A                        }
6639143Ssteve.reinhardt@amd.com                    }
6649143Ssteve.reinhardt@amd.com                } else {
6659143Ssteve.reinhardt@amd.com                    return new Unknown(machInst);
66610932Sbrandon.potter@amd.com                }
667360SN/A            } else {
668360SN/A                if (u) {
66910027SChris.Adeniyi-Jones@arm.com                    if (bits(c, 1) == 0) {
67010027SChris.Adeniyi-Jones@arm.com                        if (q) {
67110027SChris.Adeniyi-Jones@arm.com                            return new VcgeQFp<float>(machInst, vd, vn, vm);
67210027SChris.Adeniyi-Jones@arm.com                        } else {
67310027SChris.Adeniyi-Jones@arm.com                            return new VcgeDFp<float>(machInst, vd, vn, vm);
67410027SChris.Adeniyi-Jones@arm.com                        }
67510027SChris.Adeniyi-Jones@arm.com                    } else {
67610027SChris.Adeniyi-Jones@arm.com                        if (q) {
67710027SChris.Adeniyi-Jones@arm.com                            return new VcgtQFp<float>(machInst, vd, vn, vm);
67810027SChris.Adeniyi-Jones@arm.com                        } else {
67910027SChris.Adeniyi-Jones@arm.com                            return new VcgtDFp<float>(machInst, vd, vn, vm);
68010027SChris.Adeniyi-Jones@arm.com                        }
68110027SChris.Adeniyi-Jones@arm.com                    }
68210027SChris.Adeniyi-Jones@arm.com                } else {
68310027SChris.Adeniyi-Jones@arm.com                    if (bits(c, 1) == 0) {
68410027SChris.Adeniyi-Jones@arm.com                        if (q) {
68510027SChris.Adeniyi-Jones@arm.com                            return new VceqQFp<float>(machInst, vd, vn, vm);
68610027SChris.Adeniyi-Jones@arm.com                        } else {
68710027SChris.Adeniyi-Jones@arm.com                            return new VceqDFp<float>(machInst, vd, vn, vm);
68810027SChris.Adeniyi-Jones@arm.com                        }
68910027SChris.Adeniyi-Jones@arm.com                    } else {
69010027SChris.Adeniyi-Jones@arm.com                        return new Unknown(machInst);
69110633Smichaelupton@gmail.com                    }
69210633Smichaelupton@gmail.com                }
69310633Smichaelupton@gmail.com            }
69410633Smichaelupton@gmail.com          case 0xf:
69510633Smichaelupton@gmail.com            if (b) {
69610633Smichaelupton@gmail.com                if (u) {
69710633Smichaelupton@gmail.com                    return new Unknown(machInst);
69810633Smichaelupton@gmail.com                } else {
69910633Smichaelupton@gmail.com                    if (bits(c, 1) == 0) {
70010633Smichaelupton@gmail.com                        if (q) {
70110633Smichaelupton@gmail.com                            return new VrecpsQFp<float>(machInst, vd, vn, vm);
70210633Smichaelupton@gmail.com                        } else {
70310633Smichaelupton@gmail.com                            return new VrecpsDFp<float>(machInst, vd, vn, vm);
70410633Smichaelupton@gmail.com                        }
70510203SAli.Saidi@ARM.com                    } else {
70610203SAli.Saidi@ARM.com                        if (q) {
70710203SAli.Saidi@ARM.com                            return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
70810203SAli.Saidi@ARM.com                        } else {
70910203SAli.Saidi@ARM.com                            return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
71010203SAli.Saidi@ARM.com                        }
71110203SAli.Saidi@ARM.com                    }
71210203SAli.Saidi@ARM.com                }
71310203SAli.Saidi@ARM.com            } else {
71410203SAli.Saidi@ARM.com                if (u) {
71510203SAli.Saidi@ARM.com                    if (bits(c, 1) == 0) {
71610203SAli.Saidi@ARM.com                        if (q) {
71710203SAli.Saidi@ARM.com                            return new VpmaxQFp<float>(machInst, vd, vn, vm);
71810203SAli.Saidi@ARM.com                        } else {
71910203SAli.Saidi@ARM.com                            return new VpmaxDFp<float>(machInst, vd, vn, vm);
72010203SAli.Saidi@ARM.com                        }
72110203SAli.Saidi@ARM.com                    } else {
72210203SAli.Saidi@ARM.com                        if (q) {
72310203SAli.Saidi@ARM.com                            return new VpminQFp<float>(machInst, vd, vn, vm);
72410203SAli.Saidi@ARM.com                        } else {
72510203SAli.Saidi@ARM.com                            return new VpminDFp<float>(machInst, vd, vn, vm);
72610203SAli.Saidi@ARM.com                        }
72710203SAli.Saidi@ARM.com                    }
72810203SAli.Saidi@ARM.com                } else {
72910203SAli.Saidi@ARM.com                    if (bits(c, 1) == 0) {
73010203SAli.Saidi@ARM.com                        if (q) {
73110850SGiacomo.Gabrielli@arm.com                            return new VmaxQFp<float>(machInst, vd, vn, vm);
73210850SGiacomo.Gabrielli@arm.com                        } else {
73310850SGiacomo.Gabrielli@arm.com                            return new VmaxDFp<float>(machInst, vd, vn, vm);
73410850SGiacomo.Gabrielli@arm.com                        }
73510850SGiacomo.Gabrielli@arm.com                    } else {
73610850SGiacomo.Gabrielli@arm.com                        if (q) {
73710850SGiacomo.Gabrielli@arm.com                            return new VminQFp<float>(machInst, vd, vn, vm);
73810850SGiacomo.Gabrielli@arm.com                        } else {
73910850SGiacomo.Gabrielli@arm.com                            return new VminDFp<float>(machInst, vd, vn, vm);
74010850SGiacomo.Gabrielli@arm.com                        }
74110850SGiacomo.Gabrielli@arm.com                    }
74210850SGiacomo.Gabrielli@arm.com                }
74310850SGiacomo.Gabrielli@arm.com            }
74410850SGiacomo.Gabrielli@arm.com        }
74510850SGiacomo.Gabrielli@arm.com        return new Unknown(machInst);
74610850SGiacomo.Gabrielli@arm.com    }
74710850SGiacomo.Gabrielli@arm.com
74810850SGiacomo.Gabrielli@arm.com    static StaticInstPtr
74910850SGiacomo.Gabrielli@arm.com    decodeNeonOneRegModImm(ExtMachInst machInst)
75010850SGiacomo.Gabrielli@arm.com    {
75110850SGiacomo.Gabrielli@arm.com        const IntRegIndex vd =
75210850SGiacomo.Gabrielli@arm.com            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
75310850SGiacomo.Gabrielli@arm.com                               (bits(machInst, 22) << 4)));
75410850SGiacomo.Gabrielli@arm.com        const bool q = bits(machInst, 6);
75510850SGiacomo.Gabrielli@arm.com        const bool op = bits(machInst, 5);
75610850SGiacomo.Gabrielli@arm.com        const uint8_t cmode = bits(machInst, 11, 8);
75710850SGiacomo.Gabrielli@arm.com        const uint8_t imm = ((THUMB ? bits(machInst, 28) :
75810850SGiacomo.Gabrielli@arm.com                                      bits(machInst, 24)) << 7) |
75910850SGiacomo.Gabrielli@arm.com                            (bits(machInst, 18, 16) << 4) |
76010850SGiacomo.Gabrielli@arm.com                            (bits(machInst, 3, 0) << 0);
76110850SGiacomo.Gabrielli@arm.com        const uint64_t bigImm = simd_modified_imm(op, cmode, imm);
76210850SGiacomo.Gabrielli@arm.com        if (op) {
76310850SGiacomo.Gabrielli@arm.com            if (bits(cmode, 3) == 0) {
76410850SGiacomo.Gabrielli@arm.com                if (bits(cmode, 0) == 0) {
76510850SGiacomo.Gabrielli@arm.com                    if (q)
76610850SGiacomo.Gabrielli@arm.com                        return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
7676640Svince@csl.cornell.edu                    else
7686640Svince@csl.cornell.edu                        return new NVmvniD<uint64_t>(machInst, vd, bigImm);
7696640Svince@csl.cornell.edu                } else {
7706640Svince@csl.cornell.edu                    if (q)
7716640Svince@csl.cornell.edu                        return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
7726640Svince@csl.cornell.edu                    else
7736640Svince@csl.cornell.edu                        return new NVbiciD<uint64_t>(machInst, vd, bigImm);
7746701Sgblack@eecs.umich.edu                }
7756701Sgblack@eecs.umich.edu            } else {
77610793Sbrandon.potter@amd.com                if (bits(cmode, 2) == 1) {
7776640Svince@csl.cornell.edu                    switch (bits(cmode, 1, 0)) {
7786701Sgblack@eecs.umich.edu                      case 0:
7796701Sgblack@eecs.umich.edu                      case 1:
7806640Svince@csl.cornell.edu                        if (q)
7818706Sandreas.hansson@arm.com                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
7826640Svince@csl.cornell.edu                        else
7836701Sgblack@eecs.umich.edu                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
7846640Svince@csl.cornell.edu                      case 2:
785360SN/A                        if (q)
7861999SN/A                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
7871999SN/A                        else
7881999SN/A                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
7893114Sgblack@eecs.umich.edu                      case 3:
7902680Sktlim@umich.edu                        if (q)
7911999SN/A                            return new Unknown(machInst);
7921999SN/A                        else
7931999SN/A                            return new Unknown(machInst);
7946701Sgblack@eecs.umich.edu                    }
7958852Sandreas.hansson@arm.com                } else {
7966701Sgblack@eecs.umich.edu                    if (bits(cmode, 0) == 0) {
7971999SN/A                        if (q)
7986701Sgblack@eecs.umich.edu                            return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
7991999SN/A                        else
8006701Sgblack@eecs.umich.edu                            return new NVmvniD<uint64_t>(machInst, vd, bigImm);
8011999SN/A                    } else {
8021999SN/A                        if (q)
8031999SN/A                            return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
8041999SN/A                        else
8051999SN/A                            return new NVbiciD<uint64_t>(machInst, vd, bigImm);
8063669Sbinkertn@umich.edu                    }
8073669Sbinkertn@umich.edu                }
8083669Sbinkertn@umich.edu            }
8091999SN/A        } else {
8101999SN/A            if (bits(cmode, 3) == 0) {
8111999SN/A                if (bits(cmode, 0) == 0) {
8122218SN/A                    if (q)
8131999SN/A                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8141999SN/A                    else
8151999SN/A                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8161999SN/A                } else {
8171999SN/A                    if (q)
8181999SN/A                        return new NVorriQ<uint64_t>(machInst, vd, bigImm);
8191999SN/A                    else
8201999SN/A                        return new NVorriD<uint64_t>(machInst, vd, bigImm);
8213114Sgblack@eecs.umich.edu                }
8222680Sktlim@umich.edu            } else {
8231999SN/A                if (bits(cmode, 2) == 1) {
8246701Sgblack@eecs.umich.edu                    if (q)
82510931Sbrandon.potter@amd.com                        return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
82610931Sbrandon.potter@amd.com                    else
82710931Sbrandon.potter@amd.com                        return new NVmoviD<uint64_t>(machInst, vd, bigImm);
82810932Sbrandon.potter@amd.com                } else {
82910931Sbrandon.potter@amd.com                    if (bits(cmode, 0) == 0) {
8301999SN/A                        if (q)
8311999SN/A                            return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
8321999SN/A                        else
8331999SN/A                            return new NVmoviD<uint64_t>(machInst, vd, bigImm);
8341999SN/A                    } else {
8351999SN/A                        if (q)
8361999SN/A                            return new NVorriQ<uint64_t>(machInst, vd, bigImm);
8371999SN/A                        else
83810931Sbrandon.potter@amd.com                            return new NVorriD<uint64_t>(machInst, vd, bigImm);
8391999SN/A                    }
8402218SN/A                }
8411999SN/A            }
8421999SN/A        }
8431999SN/A        return new Unknown(machInst);
8441999SN/A    }
8455877Shsul@eecs.umich.edu
8465877Shsul@eecs.umich.edu    static StaticInstPtr
8475877Shsul@eecs.umich.edu    decodeNeonTwoRegAndShift(ExtMachInst machInst)
8485877Shsul@eecs.umich.edu    {
8495877Shsul@eecs.umich.edu        const uint32_t a = bits(machInst, 11, 8);
8506701Sgblack@eecs.umich.edu        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
8516701Sgblack@eecs.umich.edu        const bool b = bits(machInst, 6);
8526701Sgblack@eecs.umich.edu        const bool l = bits(machInst, 7);
8536701Sgblack@eecs.umich.edu        const IntRegIndex vd =
8546701Sgblack@eecs.umich.edu            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
85510027SChris.Adeniyi-Jones@arm.com                               (bits(machInst, 22) << 4)));
85610027SChris.Adeniyi-Jones@arm.com        const IntRegIndex vm =
85710027SChris.Adeniyi-Jones@arm.com            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
85810027SChris.Adeniyi-Jones@arm.com                               (bits(machInst, 5) << 4)));
85910027SChris.Adeniyi-Jones@arm.com        unsigned imm6 = bits(machInst, 21, 16);
8605877Shsul@eecs.umich.edu        unsigned imm = ((l ? 1 : 0) << 6) | imm6;
86110318Sandreas.hansson@arm.com        unsigned size = 3;
86210318Sandreas.hansson@arm.com        unsigned lShiftAmt = 0;
8635877Shsul@eecs.umich.edu        unsigned bitSel;
8645877Shsul@eecs.umich.edu        for (bitSel = 1 << 6; true; bitSel >>= 1) {
8655877Shsul@eecs.umich.edu            if (bitSel & imm)
8665877Shsul@eecs.umich.edu                break;
86710486Stjablin@gmail.com            else if (!size)
86810486Stjablin@gmail.com                return new Unknown(machInst);
8695877Shsul@eecs.umich.edu            size--;
87010027SChris.Adeniyi-Jones@arm.com        }
87110027SChris.Adeniyi-Jones@arm.com        lShiftAmt = imm6 & ~bitSel;
8725877Shsul@eecs.umich.edu        unsigned rShiftAmt = 0;
8738601Ssteve.reinhardt@amd.com        if (a != 0xe && a != 0xf) {
8745877Shsul@eecs.umich.edu            if (size > 2)
8755877Shsul@eecs.umich.edu                rShiftAmt = 64 - imm6;
8765877Shsul@eecs.umich.edu            else
87710027SChris.Adeniyi-Jones@arm.com                rShiftAmt = 2 * (8 << size) - imm6;
8785877Shsul@eecs.umich.edu        }
8795877Shsul@eecs.umich.edu
8805877Shsul@eecs.umich.edu        switch (a) {
88110027SChris.Adeniyi-Jones@arm.com          case 0x0:
88210027SChris.Adeniyi-Jones@arm.com            return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
88310027SChris.Adeniyi-Jones@arm.com                    b, u, size, machInst, vd, vm, rShiftAmt);
88410027SChris.Adeniyi-Jones@arm.com          case 0x1:
88510027SChris.Adeniyi-Jones@arm.com            return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
88610027SChris.Adeniyi-Jones@arm.com                    b, u, size, machInst, vd, vm, rShiftAmt);
8875877Shsul@eecs.umich.edu          case 0x2:
88810027SChris.Adeniyi-Jones@arm.com            return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
88910027SChris.Adeniyi-Jones@arm.com                    b, u, size, machInst, vd, vm, rShiftAmt);
89010027SChris.Adeniyi-Jones@arm.com          case 0x3:
89110027SChris.Adeniyi-Jones@arm.com            return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
89210027SChris.Adeniyi-Jones@arm.com                    b, u, size, machInst, vd, vm, rShiftAmt);
89310027SChris.Adeniyi-Jones@arm.com          case 0x4:
89410027SChris.Adeniyi-Jones@arm.com            if (u) {
89510027SChris.Adeniyi-Jones@arm.com                return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
89610027SChris.Adeniyi-Jones@arm.com                        b, size, machInst, vd, vm, rShiftAmt);
89710027SChris.Adeniyi-Jones@arm.com            } else {
89810027SChris.Adeniyi-Jones@arm.com                return new Unknown(machInst);
89910027SChris.Adeniyi-Jones@arm.com            }
90010027SChris.Adeniyi-Jones@arm.com          case 0x5:
9015877Shsul@eecs.umich.edu            if (u) {
9025877Shsul@eecs.umich.edu                return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
9035877Shsul@eecs.umich.edu                        b, size, machInst, vd, vm, lShiftAmt);
90410027SChris.Adeniyi-Jones@arm.com            } else {
90510027SChris.Adeniyi-Jones@arm.com                return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
9068601Ssteve.reinhardt@amd.com                        b, size, machInst, vd, vm, lShiftAmt);
90710027SChris.Adeniyi-Jones@arm.com            }
9085877Shsul@eecs.umich.edu          case 0x6:
9095877Shsul@eecs.umich.edu          case 0x7:
9101999SN/A            if (u) {
911378SN/A                if (a == 0x6) {
912360SN/A                    return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
9131450SN/A                            b, size, machInst, vd, vm, lShiftAmt);
9143114Sgblack@eecs.umich.edu                } else {
9152680Sktlim@umich.edu                    return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
916360SN/A                            b, size, machInst, vd, vm, lShiftAmt);
917360SN/A                }
918360SN/A            } else {
9196701Sgblack@eecs.umich.edu                return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
9208852Sandreas.hansson@arm.com                        b, size, machInst, vd, vm, lShiftAmt);
9216701Sgblack@eecs.umich.edu            }
9226701Sgblack@eecs.umich.edu          case 0x8:
9236701Sgblack@eecs.umich.edu            if (l) {
9246701Sgblack@eecs.umich.edu                return new Unknown(machInst);
925360SN/A            } else if (u) {
9263669Sbinkertn@umich.edu                return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
9273669Sbinkertn@umich.edu                        b, size, machInst, vd, vm, rShiftAmt);
9283669Sbinkertn@umich.edu            } else {
929360SN/A                return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
930360SN/A                        b, size, machInst, vd, vm, rShiftAmt);
931360SN/A            }
932360SN/A          case 0x9:
9332218SN/A            if (l) {
934360SN/A                return new Unknown(machInst);
9358706Sandreas.hansson@arm.com            } else if (u) {
936360SN/A                return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
9371458SN/A                        b, size, machInst, vd, vm, rShiftAmt);
938360SN/A            } else {
939360SN/A                return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
940360SN/A                        b, size, machInst, vd, vm, rShiftAmt);
9415074Ssaidi@eecs.umich.edu            }
9425074Ssaidi@eecs.umich.edu          case 0xa:
9435074Ssaidi@eecs.umich.edu            if (l || b) {
9445074Ssaidi@eecs.umich.edu                return new Unknown(machInst);
9455074Ssaidi@eecs.umich.edu            } else {
9465074Ssaidi@eecs.umich.edu                return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
9475074Ssaidi@eecs.umich.edu                        lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
9485074Ssaidi@eecs.umich.edu            }
9496701Sgblack@eecs.umich.edu          case 0xe:
9508852Sandreas.hansson@arm.com            if (l) {
9516701Sgblack@eecs.umich.edu                return new Unknown(machInst);
9525074Ssaidi@eecs.umich.edu            } else {
9536701Sgblack@eecs.umich.edu                if (bits(imm6, 5) == 0)
9545074Ssaidi@eecs.umich.edu                    return new Unknown(machInst);
9555074Ssaidi@eecs.umich.edu                if (u) {
9565074Ssaidi@eecs.umich.edu                    if (b) {
9575074Ssaidi@eecs.umich.edu                        return new NVcvtu2fpQ<float>(
9585208Ssaidi@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9595208Ssaidi@eecs.umich.edu                    } else {
9605208Ssaidi@eecs.umich.edu                        return new NVcvtu2fpD<float>(
9615208Ssaidi@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9625074Ssaidi@eecs.umich.edu                    }
9635074Ssaidi@eecs.umich.edu                } else {
9645208Ssaidi@eecs.umich.edu                    if (b) {
9655074Ssaidi@eecs.umich.edu                        return new NVcvts2fpQ<float>(
9665074Ssaidi@eecs.umich.edu                                machInst, vd, vm, 64 - imm6);
9675074Ssaidi@eecs.umich.edu                    } else {
9685074Ssaidi@eecs.umich.edu                        return new NVcvts2fpD<float>(
9698706Sandreas.hansson@arm.com                                machInst, vd, vm, 64 - imm6);
9705074Ssaidi@eecs.umich.edu                    }
9715074Ssaidi@eecs.umich.edu                }
9725074Ssaidi@eecs.umich.edu            }
9735074Ssaidi@eecs.umich.edu          case 0xf:
9745074Ssaidi@eecs.umich.edu            if (l) {
97510027SChris.Adeniyi-Jones@arm.com                return new Unknown(machInst);
97610027SChris.Adeniyi-Jones@arm.com            } else {
97710027SChris.Adeniyi-Jones@arm.com                if (bits(imm6, 5) == 0)
97810027SChris.Adeniyi-Jones@arm.com                    return new Unknown(machInst);
97910027SChris.Adeniyi-Jones@arm.com                if (u) {
98010027SChris.Adeniyi-Jones@arm.com                    if (b) {
98110027SChris.Adeniyi-Jones@arm.com                        return new NVcvt2ufxQ<float>(
98210027SChris.Adeniyi-Jones@arm.com                                machInst, vd, vm, 64 - imm6);
98310027SChris.Adeniyi-Jones@arm.com                    } else {
98410793Sbrandon.potter@amd.com                        return new NVcvt2ufxD<float>(
98510027SChris.Adeniyi-Jones@arm.com                                machInst, vd, vm, 64 - imm6);
98610027SChris.Adeniyi-Jones@arm.com                    }
98710027SChris.Adeniyi-Jones@arm.com                } else {
98810027SChris.Adeniyi-Jones@arm.com                    if (b) {
98910027SChris.Adeniyi-Jones@arm.com                        return new NVcvt2sfxQ<float>(
99010027SChris.Adeniyi-Jones@arm.com                                machInst, vd, vm, 64 - imm6);
99110027SChris.Adeniyi-Jones@arm.com                    } else {
99210027SChris.Adeniyi-Jones@arm.com                        return new NVcvt2sfxD<float>(
99310027SChris.Adeniyi-Jones@arm.com                                machInst, vd, vm, 64 - imm6);
99410027SChris.Adeniyi-Jones@arm.com                    }
99510027SChris.Adeniyi-Jones@arm.com                }
99610027SChris.Adeniyi-Jones@arm.com            }
99710027SChris.Adeniyi-Jones@arm.com        }
99810027SChris.Adeniyi-Jones@arm.com        return new Unknown(machInst);
99910027SChris.Adeniyi-Jones@arm.com    }
100010027SChris.Adeniyi-Jones@arm.com
100110027SChris.Adeniyi-Jones@arm.com    static StaticInstPtr
100210027SChris.Adeniyi-Jones@arm.com    decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
100310027SChris.Adeniyi-Jones@arm.com    {
100410027SChris.Adeniyi-Jones@arm.com        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
100510027SChris.Adeniyi-Jones@arm.com        const uint32_t a = bits(machInst, 11, 8);
100610027SChris.Adeniyi-Jones@arm.com        const IntRegIndex vd =
100710027SChris.Adeniyi-Jones@arm.com            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
100810027SChris.Adeniyi-Jones@arm.com                               (bits(machInst, 22) << 4)));
100910027SChris.Adeniyi-Jones@arm.com        const IntRegIndex vn =
101010027SChris.Adeniyi-Jones@arm.com            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
101110027SChris.Adeniyi-Jones@arm.com                               (bits(machInst, 7) << 4)));
10121999SN/A        const IntRegIndex vm =
10131999SN/A            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
10141999SN/A                               (bits(machInst, 5) << 4)));
10153114Sgblack@eecs.umich.edu        const unsigned size = bits(machInst, 21, 20);
10162680Sktlim@umich.edu        switch (a) {
10171999SN/A          case 0x0:
10186701Sgblack@eecs.umich.edu            return decodeNeonUSThreeUSReg<Vaddl>(
101910931Sbrandon.potter@amd.com                    u, size, machInst, vd, vn, vm);
10206701Sgblack@eecs.umich.edu          case 0x1:
102110931Sbrandon.potter@amd.com            return decodeNeonUSThreeUSReg<Vaddw>(
102210932Sbrandon.potter@amd.com                    u, size, machInst, vd, vn, vm);
102310931Sbrandon.potter@amd.com          case 0x2:
10241999SN/A            return decodeNeonUSThreeUSReg<Vsubl>(
10251999SN/A                    u, size, machInst, vd, vn, vm);
10262764Sstever@eecs.umich.edu          case 0x3:
10272064SN/A            return decodeNeonUSThreeUSReg<Vsubw>(
102810931Sbrandon.potter@amd.com                    u, size, machInst, vd, vn, vm);
10292064SN/A          case 0x4:
10302064SN/A            if (u) {
103110931Sbrandon.potter@amd.com                return decodeNeonUThreeUSReg<Vraddhn>(
10322064SN/A                        size, machInst, vd, vn, vm);
10331999SN/A            } else {
10341999SN/A                return decodeNeonUThreeUSReg<Vaddhn>(
10352218SN/A                        size, machInst, vd, vn, vm);
10361999SN/A            }
103710931Sbrandon.potter@amd.com          case 0x5:
10381999SN/A            return decodeNeonUSThreeUSReg<Vabal>(
10391999SN/A                    u, size, machInst, vd, vn, vm);
10401999SN/A          case 0x6:
10411999SN/A            if (u) {
10421999SN/A                return decodeNeonUThreeUSReg<Vrsubhn>(
1043378SN/A                        size, machInst, vd, vn, vm);
1044360SN/A            } else {
10451450SN/A                return decodeNeonUThreeUSReg<Vsubhn>(
10463114Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10472680Sktlim@umich.edu            }
1048360SN/A          case 0x7:
1049360SN/A            if (bits(machInst, 23)) {
1050360SN/A                return decodeNeonUSThreeUSReg<Vabdl>(
10516701Sgblack@eecs.umich.edu                        u, size, machInst, vd, vn, vm);
10528852Sandreas.hansson@arm.com            } else {
10536701Sgblack@eecs.umich.edu                return decodeNeonUSThreeReg<VabdD, VabdQ>(
10546701Sgblack@eecs.umich.edu                        bits(machInst, 6), u, size, machInst, vd, vn, vm);
10556701Sgblack@eecs.umich.edu            }
10566701Sgblack@eecs.umich.edu          case 0x8:
1057360SN/A            return decodeNeonUSThreeUSReg<Vmlal>(
10583669Sbinkertn@umich.edu                    u, size, machInst, vd, vn, vm);
10593669Sbinkertn@umich.edu          case 0xa:
10603669Sbinkertn@umich.edu            return decodeNeonUSThreeUSReg<Vmlsl>(
1061360SN/A                    u, size, machInst, vd, vn, vm);
1062360SN/A          case 0x9:
1063360SN/A            if (u) {
1064360SN/A                return new Unknown(machInst);
10651458SN/A            } else {
1066360SN/A                return decodeNeonSThreeUSReg<Vqdmlal>(
10678706Sandreas.hansson@arm.com                        size, machInst, vd, vn, vm);
1068360SN/A            }
10691458SN/A          case 0xb:
1070360SN/A            if (u) {
1071360SN/A                return new Unknown(machInst);
10721999SN/A            } else {
10731999SN/A                return decodeNeonSThreeUSReg<Vqdmlsl>(
10741999SN/A                        size, machInst, vd, vn, vm);
10753114Sgblack@eecs.umich.edu            }
10762680Sktlim@umich.edu          case 0xc:
10771999SN/A            return decodeNeonUSThreeUSReg<Vmull>(
10781999SN/A                    u, size, machInst, vd, vn, vm);
10791999SN/A          case 0xd:
10806701Sgblack@eecs.umich.edu            if (u) {
10818852Sandreas.hansson@arm.com                return new Unknown(machInst);
10826701Sgblack@eecs.umich.edu            } else {
10836701Sgblack@eecs.umich.edu                return decodeNeonSThreeUSReg<Vqdmull>(
10846701Sgblack@eecs.umich.edu                        size, machInst, vd, vn, vm);
10856701Sgblack@eecs.umich.edu            }
10861999SN/A          case 0xe:
10873669Sbinkertn@umich.edu            return decodeNeonUThreeUSReg<Vmullp>(
10883669Sbinkertn@umich.edu                    size, machInst, vd, vn, vm);
10893669Sbinkertn@umich.edu        }
10902764Sstever@eecs.umich.edu        return new Unknown(machInst);
10912064SN/A    }
10922064SN/A
10932064SN/A    static StaticInstPtr
10941999SN/A    decodeNeonTwoRegScalar(ExtMachInst machInst)
10951999SN/A    {
10962064SN/A        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
10971999SN/A        const uint32_t a = bits(machInst, 11, 8);
10981999SN/A        const unsigned size = bits(machInst, 21, 20);
10991999SN/A        const IntRegIndex vd =
11001999SN/A            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
11018706Sandreas.hansson@arm.com                               (bits(machInst, 22) << 4)));
11021999SN/A        const IntRegIndex vn =
11031999SN/A            (IntRegIndex)(2 * (bits(machInst, 19, 16) |
11041999SN/A                               (bits(machInst, 7) << 4)));
11051999SN/A        const IntRegIndex vm = (size == 2) ?
1106378SN/A            (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1107360SN/A            (IntRegIndex)(2 * bits(machInst, 2, 0));
11081450SN/A        const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
11093114Sgblack@eecs.umich.edu            (bits(machInst, 3) | (bits(machInst, 5) << 1));
11102680Sktlim@umich.edu        switch (a) {
1111360SN/A          case 0x0:
11126701Sgblack@eecs.umich.edu            if (u) {
111310931Sbrandon.potter@amd.com                switch (size) {
11146701Sgblack@eecs.umich.edu                  case 1:
1115360SN/A                    return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
111611380Salexandru.dutu@amd.com                  case 2:
1117360SN/A                    return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
111810932Sbrandon.potter@amd.com                  default:
111910931Sbrandon.potter@amd.com                    return new Unknown(machInst);
11201458SN/A                }
1121360SN/A            } else {
1122360SN/A                switch (size) {
112310931Sbrandon.potter@amd.com                  case 1:
1124360SN/A                    return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1125360SN/A                  case 2:
11261458SN/A                    return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1127360SN/A                  default:
112810931Sbrandon.potter@amd.com                    return new Unknown(machInst);
11292021SN/A                }
11301458SN/A            }
1131360SN/A          case 0x1:
1132360SN/A            if (u)
1133360SN/A                return new VmlasQFp<float>(machInst, vd, vn, vm, index);
11341706SN/A            else
11351706SN/A                return new VmlasDFp<float>(machInst, vd, vn, vm, index);
11361706SN/A          case 0x4:
11373114Sgblack@eecs.umich.edu            if (u) {
11382680Sktlim@umich.edu                switch (size) {
11391706SN/A                  case 1:
11401706SN/A                    return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
11411706SN/A                  case 2:
11426701Sgblack@eecs.umich.edu                    return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
11438852Sandreas.hansson@arm.com                  default:
11446701Sgblack@eecs.umich.edu                    return new Unknown(machInst);
11456701Sgblack@eecs.umich.edu                }
11466701Sgblack@eecs.umich.edu            } else {
11476701Sgblack@eecs.umich.edu                switch (size) {
11481706SN/A                  case 1:
11493669Sbinkertn@umich.edu                    return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
11503669Sbinkertn@umich.edu                  case 2:
11513669Sbinkertn@umich.edu                    return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
11521706SN/A                  default:
11531706SN/A                    return new Unknown(machInst);
11541706SN/A                }
11551706SN/A            }
11562218SN/A          case 0x5:
11571706SN/A            if (u)
11588706Sandreas.hansson@arm.com                return new VmlssQFp<float>(machInst, vd, vn, vm, index);
11591706SN/A            else
11601706SN/A                return new VmlssDFp<float>(machInst, vd, vn, vm, index);
11611706SN/A          case 0x2:
11621706SN/A            if (u) {
11631706SN/A                switch (size) {
11641706SN/A                  case 1:
11651706SN/A                    return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
11661706SN/A                  case 2:
11673114Sgblack@eecs.umich.edu                    return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
11682680Sktlim@umich.edu                  default:
11691706SN/A                    return new Unknown(machInst);
11706701Sgblack@eecs.umich.edu                }
117110931Sbrandon.potter@amd.com            } else {
11726701Sgblack@eecs.umich.edu                switch (size) {
11731706SN/A                  case 1:
117410932Sbrandon.potter@amd.com                    return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
117510931Sbrandon.potter@amd.com                  case 2:
11761706SN/A                    return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
11771706SN/A                  default:
11781706SN/A                    return new Unknown(machInst);
117910931Sbrandon.potter@amd.com                }
11801706SN/A            }
11811706SN/A          case 0x6:
11822218SN/A            if (u) {
11831706SN/A                switch (size) {
11848706Sandreas.hansson@arm.com                  case 1:
11851706SN/A                    return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
11861706SN/A                  case 2:
11871706SN/A                    return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
11881706SN/A                  default:
11891706SN/A                    return new Unknown(machInst);
11901999SN/A                }
11911999SN/A            } else {
11921999SN/A                switch (size) {
11933114Sgblack@eecs.umich.edu                  case 1:
11942680Sktlim@umich.edu                    return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
11951999SN/A                  case 2:
11966701Sgblack@eecs.umich.edu                    return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
119710931Sbrandon.potter@amd.com                  default:
119810931Sbrandon.potter@amd.com                    return new Unknown(machInst);
119910932Sbrandon.potter@amd.com                }
120010931Sbrandon.potter@amd.com            }
12011999SN/A          case 0x3:
12021999SN/A            if (u) {
12038852Sandreas.hansson@arm.com                return new Unknown(machInst);
12046701Sgblack@eecs.umich.edu            } else {
12056701Sgblack@eecs.umich.edu                switch (size) {
12061999SN/A                  case 1:
12076227Snate@binkert.org                    return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
12081999SN/A                  case 2:
12092461SN/A                    return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
12108852Sandreas.hansson@arm.com                  default:
12118852Sandreas.hansson@arm.com                    return new Unknown(machInst);
12128737Skoansin.tan@gmail.com                }
12131999SN/A            }
12148852Sandreas.hansson@arm.com          case 0x7:
12158852Sandreas.hansson@arm.com            if (u) {
12161999SN/A                return new Unknown(machInst);
12171999SN/A            } else {
121810931Sbrandon.potter@amd.com                switch (size) {
12191999SN/A                  case 1:
12206227Snate@binkert.org                    return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
12211999SN/A                  case 2:
12221999SN/A                    return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
12231999SN/A                  default:
12242218SN/A                    return new Unknown(machInst);
12251999SN/A                }
122610629Sjthestness@gmail.com            }
12271999SN/A          case 0x8:
12281999SN/A            if (u) {
122911385Sbrandon.potter@amd.com                switch (size) {
1230360SN/A                  case 1:
12311450SN/A                    return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
123211385Sbrandon.potter@amd.com                  case 2:
123311385Sbrandon.potter@amd.com                    return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1234360SN/A                  default:
12356701Sgblack@eecs.umich.edu                    return new Unknown(machInst);
12366701Sgblack@eecs.umich.edu                }
12376701Sgblack@eecs.umich.edu            } else {
123811383Sbrandon.potter@amd.com                switch (size) {
123911383Sbrandon.potter@amd.com                  case 1:
12408324Ssteve.reinhardt@amd.com                    return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
124110486Stjablin@gmail.com                  case 2:
1242360SN/A                    return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
124311385Sbrandon.potter@amd.com                  default:
124411385Sbrandon.potter@amd.com                    return new Unknown(machInst);
12459008Sgblack@eecs.umich.edu                }
124611383Sbrandon.potter@amd.com            }
124711383Sbrandon.potter@amd.com          case 0x9:
124811383Sbrandon.potter@amd.com            if (u)
124911383Sbrandon.potter@amd.com                return new VmulsQFp<float>(machInst, vd, vn, vm, index);
125011383Sbrandon.potter@amd.com            else
125111383Sbrandon.potter@amd.com                return new VmulsDFp<float>(machInst, vd, vn, vm, index);
125211383Sbrandon.potter@amd.com          case 0xa:
125311383Sbrandon.potter@amd.com            if (u) {
125411383Sbrandon.potter@amd.com                switch (size) {
12558324Ssteve.reinhardt@amd.com                  case 1:
125611383Sbrandon.potter@amd.com                    return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
125711383Sbrandon.potter@amd.com                  case 2:
125811383Sbrandon.potter@amd.com                    return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
125911383Sbrandon.potter@amd.com                  default:
126011383Sbrandon.potter@amd.com                    return new Unknown(machInst);
126111383Sbrandon.potter@amd.com                }
126211383Sbrandon.potter@amd.com            } else {
126311383Sbrandon.potter@amd.com                switch (size) {
126411383Sbrandon.potter@amd.com                  case 1:
126511383Sbrandon.potter@amd.com                    return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
126611383Sbrandon.potter@amd.com                  case 2:
126711383Sbrandon.potter@amd.com                    return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
126811383Sbrandon.potter@amd.com                  default:
126911383Sbrandon.potter@amd.com                    return new Unknown(machInst);
127011383Sbrandon.potter@amd.com                }
127111383Sbrandon.potter@amd.com            }
127211383Sbrandon.potter@amd.com          case 0xb:
127311383Sbrandon.potter@amd.com            if (u) {
127411383Sbrandon.potter@amd.com                return new Unknown(machInst);
127511383Sbrandon.potter@amd.com            } else {
127611383Sbrandon.potter@amd.com                if (u) {
127711383Sbrandon.potter@amd.com                    switch (size) {
127811383Sbrandon.potter@amd.com                      case 1:
127911383Sbrandon.potter@amd.com                        return new Vqdmulls<uint16_t>(
12808324Ssteve.reinhardt@amd.com                                machInst, vd, vn, vm, index);
12815877Shsul@eecs.umich.edu                      case 2:
128210486Stjablin@gmail.com                        return new Vqdmulls<uint32_t>(
128310486Stjablin@gmail.com                                machInst, vd, vn, vm, index);
128411383Sbrandon.potter@amd.com                      default:
128511383Sbrandon.potter@amd.com                        return new Unknown(machInst);
128611383Sbrandon.potter@amd.com                    }
128711624Smichael.lebeane@amd.com                } else {
128811624Smichael.lebeane@amd.com                    switch (size) {
128911624Smichael.lebeane@amd.com                      case 1:
129011624Smichael.lebeane@amd.com                        return new Vqdmulls<int16_t>(
129111624Smichael.lebeane@amd.com                                machInst, vd, vn, vm, index);
129211624Smichael.lebeane@amd.com                      case 2:
129311624Smichael.lebeane@amd.com                        return new Vqdmulls<int32_t>(
129411624Smichael.lebeane@amd.com                                machInst, vd, vn, vm, index);
129511624Smichael.lebeane@amd.com                      default:
129611624Smichael.lebeane@amd.com                        return new Unknown(machInst);
129711624Smichael.lebeane@amd.com                    }
129811383Sbrandon.potter@amd.com                }
129911383Sbrandon.potter@amd.com            }
1300360SN/A          case 0xc:
130111383Sbrandon.potter@amd.com            if (u) {
130211383Sbrandon.potter@amd.com                switch (size) {
13038600Ssteve.reinhardt@amd.com                  case 1:
130411383Sbrandon.potter@amd.com                    return new VqdmulhsQ<int16_t>(
130511383Sbrandon.potter@amd.com                            machInst, vd, vn, vm, index);
130611383Sbrandon.potter@amd.com                  case 2:
13078600Ssteve.reinhardt@amd.com                    return new VqdmulhsQ<int32_t>(
13082544SN/A                            machInst, vd, vn, vm, index);
13092544SN/A                  default:
131011383Sbrandon.potter@amd.com                    return new Unknown(machInst);
131111383Sbrandon.potter@amd.com                }
131211383Sbrandon.potter@amd.com            } else {
131311386Ssteve.reinhardt@amd.com                switch (size) {
131411386Ssteve.reinhardt@amd.com                  case 1:
131511383Sbrandon.potter@amd.com                    return new VqdmulhsD<int16_t>(
131611383Sbrandon.potter@amd.com                            machInst, vd, vn, vm, index);
131711383Sbrandon.potter@amd.com                  case 2:
131811383Sbrandon.potter@amd.com                    return new VqdmulhsD<int32_t>(
131911383Sbrandon.potter@amd.com                            machInst, vd, vn, vm, index);
132011383Sbrandon.potter@amd.com                  default:
132111383Sbrandon.potter@amd.com                    return new Unknown(machInst);
132211383Sbrandon.potter@amd.com                }
132311383Sbrandon.potter@amd.com            }
132411383Sbrandon.potter@amd.com          case 0xd:
132511383Sbrandon.potter@amd.com            if (u) {
132611383Sbrandon.potter@amd.com                switch (size) {
132711383Sbrandon.potter@amd.com                  case 1:
132811383Sbrandon.potter@amd.com                    return new VqrdmulhsQ<int16_t>(
132911383Sbrandon.potter@amd.com                            machInst, vd, vn, vm, index);
13308600Ssteve.reinhardt@amd.com                  case 2:
13316672Sgblack@eecs.umich.edu                    return new VqrdmulhsQ<int32_t>(
13328600Ssteve.reinhardt@amd.com                            machInst, vd, vn, vm, index);
133311383Sbrandon.potter@amd.com                  default:
133411383Sbrandon.potter@amd.com                    return new Unknown(machInst);
133511383Sbrandon.potter@amd.com                }
13368601Ssteve.reinhardt@amd.com            } else {
13372544SN/A                switch (size) {
133811383Sbrandon.potter@amd.com                  case 1:
133911383Sbrandon.potter@amd.com                    return new VqrdmulhsD<int16_t>(
134011383Sbrandon.potter@amd.com                            machInst, vd, vn, vm, index);
134111383Sbrandon.potter@amd.com                  case 2:
134211383Sbrandon.potter@amd.com                    return new VqrdmulhsD<int32_t>(
134311383Sbrandon.potter@amd.com                            machInst, vd, vn, vm, index);
134411383Sbrandon.potter@amd.com                  default:
134511383Sbrandon.potter@amd.com                    return new Unknown(machInst);
134611383Sbrandon.potter@amd.com                }
134711383Sbrandon.potter@amd.com            }
134811383Sbrandon.potter@amd.com        }
134911383Sbrandon.potter@amd.com        return new Unknown(machInst);
135011383Sbrandon.potter@amd.com    }
135111383Sbrandon.potter@amd.com
135211383Sbrandon.potter@amd.com    static StaticInstPtr
135311383Sbrandon.potter@amd.com    decodeNeonTwoRegMisc(ExtMachInst machInst)
135411383Sbrandon.potter@amd.com    {
135511383Sbrandon.potter@amd.com        const uint32_t a = bits(machInst, 17, 16);
135611383Sbrandon.potter@amd.com        const uint32_t b = bits(machInst, 10, 6);
135711383Sbrandon.potter@amd.com        const bool q = bits(machInst, 6);
135811383Sbrandon.potter@amd.com        const IntRegIndex vd =
135911383Sbrandon.potter@amd.com            (IntRegIndex)(2 * (bits(machInst, 15, 12) |
136011383Sbrandon.potter@amd.com                               (bits(machInst, 22) << 4)));
136111383Sbrandon.potter@amd.com        const IntRegIndex vm =
136211383Sbrandon.potter@amd.com            (IntRegIndex)(2 * (bits(machInst, 3, 0) |
136311383Sbrandon.potter@amd.com                               (bits(machInst, 5) << 4)));
136411383Sbrandon.potter@amd.com        const unsigned size = bits(machInst, 19, 18);
136511383Sbrandon.potter@amd.com        switch (a) {
136611383Sbrandon.potter@amd.com          case 0x0:
136711383Sbrandon.potter@amd.com            switch (bits(b, 4, 1)) {
136811383Sbrandon.potter@amd.com              case 0x0:
136911383Sbrandon.potter@amd.com                switch (size) {
137011392Sbrandon.potter@amd.com                  case 0:
137111392Sbrandon.potter@amd.com                    if (q) {
137211392Sbrandon.potter@amd.com                        return new NVrev64Q<uint8_t>(machInst, vd, vm);
137311392Sbrandon.potter@amd.com                    } else {
137411392Sbrandon.potter@amd.com                        return new NVrev64D<uint8_t>(machInst, vd, vm);
137511392Sbrandon.potter@amd.com                    }
137611392Sbrandon.potter@amd.com                  case 1:
137711392Sbrandon.potter@amd.com                    if (q) {
137811392Sbrandon.potter@amd.com                        return new NVrev64Q<uint16_t>(machInst, vd, vm);
137911392Sbrandon.potter@amd.com                    } else {
138011392Sbrandon.potter@amd.com                        return new NVrev64D<uint16_t>(machInst, vd, vm);
138111392Sbrandon.potter@amd.com                    }
138211392Sbrandon.potter@amd.com                  case 2:
138311392Sbrandon.potter@amd.com                    if (q) {
138411392Sbrandon.potter@amd.com                        return new NVrev64Q<uint32_t>(machInst, vd, vm);
138511392Sbrandon.potter@amd.com                    } else {
138611392Sbrandon.potter@amd.com                        return new NVrev64D<uint32_t>(machInst, vd, vm);
138711392Sbrandon.potter@amd.com                    }
138811392Sbrandon.potter@amd.com                  default:
138911392Sbrandon.potter@amd.com                    return new Unknown(machInst);
139011392Sbrandon.potter@amd.com                }
139111392Sbrandon.potter@amd.com              case 0x1:
139211392Sbrandon.potter@amd.com                switch (size) {
139311392Sbrandon.potter@amd.com                  case 0:
139411392Sbrandon.potter@amd.com                    if (q) {
139511383Sbrandon.potter@amd.com                        return new NVrev32Q<uint8_t>(machInst, vd, vm);
139611383Sbrandon.potter@amd.com                    } else {
139711383Sbrandon.potter@amd.com                        return new NVrev32D<uint8_t>(machInst, vd, vm);
139811383Sbrandon.potter@amd.com                    }
139911383Sbrandon.potter@amd.com                  case 1:
14001458SN/A                    if (q) {
1401360SN/A                        return new NVrev32Q<uint16_t>(machInst, vd, vm);
1402360SN/A                    } else {
140311593Santhony.gutierrez@amd.com                        return new NVrev32D<uint16_t>(machInst, vd, vm);
140411593Santhony.gutierrez@amd.com                    }
140511593Santhony.gutierrez@amd.com                  default:
140611593Santhony.gutierrez@amd.com                    return new Unknown(machInst);
140711593Santhony.gutierrez@amd.com                }
140811593Santhony.gutierrez@amd.com              case 0x2:
140911593Santhony.gutierrez@amd.com                if (size != 0) {
141011593Santhony.gutierrez@amd.com                    return new Unknown(machInst);
141111593Santhony.gutierrez@amd.com                } else if (q) {
141211593Santhony.gutierrez@amd.com                    return new NVrev16Q<uint8_t>(machInst, vd, vm);
141311593Santhony.gutierrez@amd.com                } else {
141411593Santhony.gutierrez@amd.com                    return new NVrev16D<uint8_t>(machInst, vd, vm);
141511593Santhony.gutierrez@amd.com                }
141611593Santhony.gutierrez@amd.com              case 0x4:
141711593Santhony.gutierrez@amd.com                return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
141811593Santhony.gutierrez@amd.com                        q, size, machInst, vd, vm);
141911593Santhony.gutierrez@amd.com              case 0x5:
142011594Santhony.gutierrez@amd.com                return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
142111593Santhony.gutierrez@amd.com                        q, size, machInst, vd, vm);
142211593Santhony.gutierrez@amd.com              case 0x8:
142311593Santhony.gutierrez@amd.com                return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
142411593Santhony.gutierrez@amd.com                        q, size, machInst, vd, vm);
142511385Sbrandon.potter@amd.com              case 0x9:
142611385Sbrandon.potter@amd.com                return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
142711385Sbrandon.potter@amd.com                        q, size, machInst, vd, vm);
142811385Sbrandon.potter@amd.com              case 0xa:
142911385Sbrandon.potter@amd.com                return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
143011385Sbrandon.potter@amd.com                        q, size, machInst, vd, vm);
143111385Sbrandon.potter@amd.com              case 0xb:
143211385Sbrandon.potter@amd.com                if (q)
143311385Sbrandon.potter@amd.com                    return new NVmvnQ<uint64_t>(machInst, vd, vm);
143411385Sbrandon.potter@amd.com                else
143511385Sbrandon.potter@amd.com                    return new NVmvnD<uint64_t>(machInst, vd, vm);
143611385Sbrandon.potter@amd.com              case 0xc:
143711385Sbrandon.potter@amd.com                return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
143811385Sbrandon.potter@amd.com                        q, size, machInst, vd, vm);
143911385Sbrandon.potter@amd.com              case 0xd:
144011385Sbrandon.potter@amd.com                return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1441378SN/A                        q, size, machInst, vd, vm);
1442360SN/A              case 0xe:
14431450SN/A                return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
14443114Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14452680Sktlim@umich.edu              case 0xf:
1446360SN/A                return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
14476701Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
14486701Sgblack@eecs.umich.edu              default:
14496701Sgblack@eecs.umich.edu                return new Unknown(machInst);
1450360SN/A            }
1451360SN/A          case 0x1:
14522064SN/A            switch (bits(b, 3, 1)) {
14535877Shsul@eecs.umich.edu              case 0x0:
14542064SN/A                if (bits(b, 4)) {
14558737Skoansin.tan@gmail.com                    if (q) {
14568737Skoansin.tan@gmail.com                        return new NVcgtQFp<float>(machInst, vd, vm);
14572064SN/A                    } else {
1458360SN/A                        return new NVcgtDFp<float>(machInst, vd, vm);
14595877Shsul@eecs.umich.edu                    }
14605877Shsul@eecs.umich.edu                } else {
14615877Shsul@eecs.umich.edu                    return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
14628737Skoansin.tan@gmail.com                            q, size, machInst, vd, vm);
14638737Skoansin.tan@gmail.com                }
14645877Shsul@eecs.umich.edu              case 0x1:
14655877Shsul@eecs.umich.edu                if (bits(b, 4)) {
14662064SN/A                    if (q) {
146710794Sbrandon.potter@amd.com                        return new NVcgeQFp<float>(machInst, vd, vm);
146810794Sbrandon.potter@amd.com                    } else {
14692064SN/A                        return new NVcgeDFp<float>(machInst, vd, vm);
1470360SN/A                    }
1471360SN/A                } else {
14728706Sandreas.hansson@arm.com                    return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
14731458SN/A                            q, size, machInst, vd, vm);
1474360SN/A                }
1475360SN/A              case 0x2:
147610796Sbrandon.potter@amd.com                if (bits(b, 4)) {
147710796Sbrandon.potter@amd.com                    if (q) {
147810796Sbrandon.potter@amd.com                        return new NVceqQFp<float>(machInst, vd, vm);
147910796Sbrandon.potter@amd.com                    } else {
148010796Sbrandon.potter@amd.com                        return new NVceqDFp<float>(machInst, vd, vm);
148110796Sbrandon.potter@amd.com                    }
148210796Sbrandon.potter@amd.com                } else {
148310796Sbrandon.potter@amd.com                    return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
148410796Sbrandon.potter@amd.com                            q, size, machInst, vd, vm);
148510796Sbrandon.potter@amd.com                }
148610796Sbrandon.potter@amd.com              case 0x3:
148710796Sbrandon.potter@amd.com                if (bits(b, 4)) {
148810796Sbrandon.potter@amd.com                    if (q) {
148910796Sbrandon.potter@amd.com                        return new NVcleQFp<float>(machInst, vd, vm);
149010796Sbrandon.potter@amd.com                    } else {
149110796Sbrandon.potter@amd.com                        return new NVcleDFp<float>(machInst, vd, vm);
149210796Sbrandon.potter@amd.com                    }
149310796Sbrandon.potter@amd.com                } else {
149410796Sbrandon.potter@amd.com                    return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
149511337SMichael.Lebeane@amd.com                            q, size, machInst, vd, vm);
149611337SMichael.Lebeane@amd.com                }
149711337SMichael.Lebeane@amd.com              case 0x4:
149811337SMichael.Lebeane@amd.com                if (bits(b, 4)) {
149911337SMichael.Lebeane@amd.com                    if (q) {
150011337SMichael.Lebeane@amd.com                        return new NVcltQFp<float>(machInst, vd, vm);
150111337SMichael.Lebeane@amd.com                    } else {
150211337SMichael.Lebeane@amd.com                        return new NVcltDFp<float>(machInst, vd, vm);
150311337SMichael.Lebeane@amd.com                    }
150411337SMichael.Lebeane@amd.com                } else {
150511337SMichael.Lebeane@amd.com                    return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
150611337SMichael.Lebeane@amd.com                            q, size, machInst, vd, vm);
150711337SMichael.Lebeane@amd.com                }
150811337SMichael.Lebeane@amd.com              case 0x6:
150911337SMichael.Lebeane@amd.com                if (bits(machInst, 10)) {
151011337SMichael.Lebeane@amd.com                    if (q)
151111337SMichael.Lebeane@amd.com                        return new NVabsQFp<float>(machInst, vd, vm);
1512378SN/A                    else
1513360SN/A                        return new NVabsDFp<float>(machInst, vd, vm);
15141450SN/A                } else {
15153114Sgblack@eecs.umich.edu                    return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
15162680Sktlim@umich.edu                            q, size, machInst, vd, vm);
1517360SN/A                }
15186701Sgblack@eecs.umich.edu              case 0x7:
15196701Sgblack@eecs.umich.edu                if (bits(machInst, 10)) {
1520360SN/A                    if (q)
152110796Sbrandon.potter@amd.com                        return new NVnegQFp<float>(machInst, vd, vm);
1522360SN/A                    else
15236109Ssanchezd@stanford.edu                        return new NVnegDFp<float>(machInst, vd, vm);
15246109Ssanchezd@stanford.edu                } else {
1525360SN/A                    return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
15268706Sandreas.hansson@arm.com                            q, size, machInst, vd, vm);
1527360SN/A                }
15281458SN/A            }
1529360SN/A          case 0x2:
1530360SN/A            switch (bits(b, 4, 1)) {
1531360SN/A              case 0x0:
15321999SN/A                if (q)
15331999SN/A                    return new NVswpQ<uint64_t>(machInst, vd, vm);
15341999SN/A                else
15353114Sgblack@eecs.umich.edu                    return new NVswpD<uint64_t>(machInst, vd, vm);
15362680Sktlim@umich.edu              case 0x1:
15371999SN/A                return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>(
15381999SN/A                        q, size, machInst, vd, vm);
15391999SN/A              case 0x2:
15406701Sgblack@eecs.umich.edu                return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
15418852Sandreas.hansson@arm.com                        q, size, machInst, vd, vm);
15426701Sgblack@eecs.umich.edu              case 0x3:
15436701Sgblack@eecs.umich.edu                return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
15446701Sgblack@eecs.umich.edu                        q, size, machInst, vd, vm);
15451999SN/A              case 0x4:
15466701Sgblack@eecs.umich.edu                if (b == 0x8) {
15476701Sgblack@eecs.umich.edu                    return decodeNeonUTwoMiscUSReg<NVmovn>(
15488706Sandreas.hansson@arm.com                            size, machInst, vd, vm);
15491999SN/A                } else {
15501999SN/A                    return decodeNeonSTwoMiscUSReg<NVqmovuns>(
15511999SN/A                            size, machInst, vd, vm);
15521999SN/A                }
15538737Skoansin.tan@gmail.com              case 0x5:
15548737Skoansin.tan@gmail.com                if (q) {
15551999SN/A                    return decodeNeonUTwoMiscUSReg<NVqmovun>(
15563669Sbinkertn@umich.edu                            size, machInst, vd, vm);
15573669Sbinkertn@umich.edu                } else {
15583669Sbinkertn@umich.edu                    return decodeNeonSTwoMiscUSReg<NVqmovn>(
15593669Sbinkertn@umich.edu                            size, machInst, vd, vm);
15601999SN/A                }
15611999SN/A              case 0x6:
15621999SN/A                if (b == 0xc) {
15631999SN/A                    const IntRegIndex vd =
15641999SN/A                        (IntRegIndex)(2 * (bits(machInst, 15, 12) |
15651999SN/A                                           (bits(machInst, 22) << 4)));
15661999SN/A                    const IntRegIndex vm =
1567378SN/A                        (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1568360SN/A                                           (bits(machInst, 5) << 4)));
15691450SN/A                    unsigned size = bits(machInst, 19, 18);
15703114Sgblack@eecs.umich.edu                    return decodeNeonSTwoShiftUSReg<NVshll>(
15712680Sktlim@umich.edu                            size, machInst, vd, vm, 8 << size);
1572360SN/A                } else {
15736701Sgblack@eecs.umich.edu                    return new Unknown(machInst);
15746701Sgblack@eecs.umich.edu                }
15756701Sgblack@eecs.umich.edu              case 0xc:
1576360SN/A              case 0xe:
15773670Sbinkertn@umich.edu                if (b == 0x18) {
15783670Sbinkertn@umich.edu                    if (size != 1 || (vm % 2))
1579360SN/A                        return new Unknown(machInst);
1580360SN/A                    return new NVcvts2h<uint16_t>(machInst, vd, vm);
1581360SN/A                } else if (b == 0x1c) {
1582360SN/A                    if (size != 1 || (vd % 2))
1583360SN/A                        return new Unknown(machInst);
1584360SN/A                    return new NVcvth2s<uint16_t>(machInst, vd, vm);
1585360SN/A                } else {
1586360SN/A                    return new Unknown(machInst);
1587360SN/A                }
1588360SN/A              default:
1589360SN/A                return new Unknown(machInst);
1590360SN/A            }
1591360SN/A          case 0x3:
1592360SN/A            if (bits(b, 4, 3) == 0x3) {
1593360SN/A                if ((q && (vd % 2 || vm % 2)) || size != 2) {
1594360SN/A                    return new Unknown(machInst);
1595360SN/A                } else {
15963670Sbinkertn@umich.edu                    if (bits(b, 2)) {
15973670Sbinkertn@umich.edu                        if (bits(b, 1)) {
159810796Sbrandon.potter@amd.com                            if (q) {
15998737Skoansin.tan@gmail.com                                return new NVcvt2ufxQ<float>(
16008737Skoansin.tan@gmail.com                                        machInst, vd, vm, 0);
16013670Sbinkertn@umich.edu                            } else {
16023670Sbinkertn@umich.edu                                return new NVcvt2ufxD<float>(
16033670Sbinkertn@umich.edu                                        machInst, vd, vm, 0);
16043670Sbinkertn@umich.edu                            }
16053670Sbinkertn@umich.edu                        } else {
16063670Sbinkertn@umich.edu                            if (q) {
16073670Sbinkertn@umich.edu                                return new NVcvt2sfxQ<float>(
16083670Sbinkertn@umich.edu                                        machInst, vd, vm, 0);
16093670Sbinkertn@umich.edu                            } else {
16103670Sbinkertn@umich.edu                                return new NVcvt2sfxD<float>(
16113670Sbinkertn@umich.edu                                        machInst, vd, vm, 0);
16123670Sbinkertn@umich.edu                            }
16133670Sbinkertn@umich.edu                        }
16148706Sandreas.hansson@arm.com                    } else {
1615360SN/A                        if (bits(b, 1)) {
16161458SN/A                            if (q) {
1617360SN/A                                return new NVcvtu2fpQ<float>(
1618360SN/A                                        machInst, vd, vm, 0);
16196683Stjones1@inf.ed.ac.uk                            } else {
16206683Stjones1@inf.ed.ac.uk                                return new NVcvtu2fpD<float>(
16216683Stjones1@inf.ed.ac.uk                                        machInst, vd, vm, 0);
16226683Stjones1@inf.ed.ac.uk                            }
16236683Stjones1@inf.ed.ac.uk                        } else {
16246683Stjones1@inf.ed.ac.uk                            if (q) {
16256701Sgblack@eecs.umich.edu                                return new NVcvts2fpQ<float>(
16266701Sgblack@eecs.umich.edu                                        machInst, vd, vm, 0);
16276683Stjones1@inf.ed.ac.uk                            } else {
16286683Stjones1@inf.ed.ac.uk                                return new NVcvts2fpD<float>(
16297823Ssteve.reinhardt@amd.com                                        machInst, vd, vm, 0);
16306683Stjones1@inf.ed.ac.uk                            }
16316683Stjones1@inf.ed.ac.uk                        }
16326683Stjones1@inf.ed.ac.uk                    }
16336683Stjones1@inf.ed.ac.uk                }
16346683Stjones1@inf.ed.ac.uk            } else if ((b & 0x1a) == 0x10) {
16356683Stjones1@inf.ed.ac.uk                if (bits(b, 2)) {
16368737Skoansin.tan@gmail.com                    if (q) {
16376683Stjones1@inf.ed.ac.uk                        return new NVrecpeQFp<float>(machInst, vd, vm);
16386683Stjones1@inf.ed.ac.uk                    } else {
16398706Sandreas.hansson@arm.com                        return new NVrecpeDFp<float>(machInst, vd, vm);
16406683Stjones1@inf.ed.ac.uk                    }
16416683Stjones1@inf.ed.ac.uk                } else {
16426683Stjones1@inf.ed.ac.uk                    if (q) {
16436683Stjones1@inf.ed.ac.uk                        return new NVrecpeQ<uint32_t>(machInst, vd, vm);
16442553SN/A                    } else {
16456684Stjones1@inf.ed.ac.uk                        return new NVrecpeD<uint32_t>(machInst, vd, vm);
16466684Stjones1@inf.ed.ac.uk                    }
16476684Stjones1@inf.ed.ac.uk                }
16486684Stjones1@inf.ed.ac.uk            } else if ((b & 0x1a) == 0x12) {
16496684Stjones1@inf.ed.ac.uk                if (bits(b, 2)) {
16506684Stjones1@inf.ed.ac.uk                    if (q) {
16516684Stjones1@inf.ed.ac.uk                        return new NVrsqrteQFp<float>(machInst, vd, vm);
165210796Sbrandon.potter@amd.com                    } else {
16536684Stjones1@inf.ed.ac.uk                        return new NVrsqrteDFp<float>(machInst, vd, vm);
16546684Stjones1@inf.ed.ac.uk                    }
16556701Sgblack@eecs.umich.edu                } else {
16566701Sgblack@eecs.umich.edu                    if (q) {
165711321Ssteve.reinhardt@amd.com                        return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
16586684Stjones1@inf.ed.ac.uk                    } else {
16598737Skoansin.tan@gmail.com                        return new NVrsqrteD<uint32_t>(machInst, vd, vm);
16608852Sandreas.hansson@arm.com                    }
16618852Sandreas.hansson@arm.com                }
16626684Stjones1@inf.ed.ac.uk            } else {
16636684Stjones1@inf.ed.ac.uk                return new Unknown(machInst);
16646684Stjones1@inf.ed.ac.uk            }
16652553SN/A        }
16662553SN/A        return new Unknown(machInst);
16671354SN/A    }
1668
1669    StaticInstPtr
1670    decodeNeonData(ExtMachInst machInst)
1671    {
1672        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1673        const uint32_t a = bits(machInst, 23, 19);
1674        const uint32_t b = bits(machInst, 11, 8);
1675        const uint32_t c = bits(machInst, 7, 4);
1676        if (bits(a, 4) == 0) {
1677            return decodeNeonThreeRegistersSameLength(machInst);
1678        } else if ((c & 0x9) == 1) {
1679            if ((a & 0x7) == 0) {
1680                return decodeNeonOneRegModImm(machInst);
1681            } else {
1682                return decodeNeonTwoRegAndShift(machInst);
1683            }
1684        } else if ((c & 0x9) == 9) {
1685            return decodeNeonTwoRegAndShift(machInst);
1686        } else if (bits(a, 2, 1) != 0x3) {
1687            if ((c & 0x5) == 0) {
1688                return decodeNeonThreeRegDiffLengths(machInst);
1689            } else if ((c & 0x5) == 4) {
1690                return decodeNeonTwoRegScalar(machInst);
1691            }
1692        } else if ((a & 0x16) == 0x16) {
1693            const IntRegIndex vd =
1694                (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1695                                   (bits(machInst, 22) << 4)));
1696            const IntRegIndex vn =
1697                (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1698                                   (bits(machInst, 7) << 4)));
1699            const IntRegIndex vm =
1700                (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1701                                   (bits(machInst, 5) << 4)));
1702            if (!u) {
1703                if (bits(c, 0) == 0) {
1704                    unsigned imm4 = bits(machInst, 11, 8);
1705                    bool q = bits(machInst, 6);
1706                    if (imm4 >= 16 && !q)
1707                        return new Unknown(machInst);
1708                    if (q) {
1709                        return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1710                    } else {
1711                        return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1712                    }
1713                }
1714            } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1715                return decodeNeonTwoRegMisc(machInst);
1716            } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1717                unsigned length = bits(machInst, 9, 8) + 1;
1718                if ((uint32_t)vn / 2 + length > 32)
1719                    return new Unknown(machInst);
1720                if (bits(machInst, 6) == 0) {
1721                    switch (length) {
1722                      case 1:
1723                        return new NVtbl1(machInst, vd, vn, vm);
1724                      case 2:
1725                        return new NVtbl2(machInst, vd, vn, vm);
1726                      case 3:
1727                        return new NVtbl3(machInst, vd, vn, vm);
1728                      case 4:
1729                        return new NVtbl4(machInst, vd, vn, vm);
1730                    }
1731                } else {
1732                    switch (length) {
1733                      case 1:
1734                        return new NVtbx1(machInst, vd, vn, vm);
1735                      case 2:
1736                        return new NVtbx2(machInst, vd, vn, vm);
1737                      case 3:
1738                        return new NVtbx3(machInst, vd, vn, vm);
1739                      case 4:
1740                        return new NVtbx4(machInst, vd, vn, vm);
1741                    }
1742                }
1743            } else if (b == 0xc && (c & 0x9) == 0) {
1744                unsigned imm4 = bits(machInst, 19, 16);
1745                if (bits(imm4, 2, 0) == 0)
1746                    return new Unknown(machInst);
1747                unsigned size = 0;
1748                while ((imm4 & 0x1) == 0) {
1749                    size++;
1750                    imm4 >>= 1;
1751                }
1752                unsigned index = imm4 >> 1;
1753                const bool q = bits(machInst, 6);
1754                return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1755                        q, size, machInst, vd, vm, index);
1756            }
1757        }
1758        return new Unknown(machInst);
1759    }
1760    '''
1761}};
1762
1763def format ThumbNeonMem() {{
1764    decode_block = '''
1765    return decodeNeonMem(machInst);
1766    '''
1767}};
1768
1769def format ThumbNeonData() {{
1770    decode_block = '''
1771    return decodeNeonData(machInst);
1772    '''
1773}};
1774
1775let {{
1776    header_output = '''
1777    StaticInstPtr
1778    decodeExtensionRegLoadStore(ExtMachInst machInst);
1779    '''
1780    decoder_output = '''
1781    StaticInstPtr
1782    decodeExtensionRegLoadStore(ExtMachInst machInst)
1783    {
1784        const uint32_t opcode = bits(machInst, 24, 20);
1785        const uint32_t offset = bits(machInst, 7, 0);
1786        const bool single = (bits(machInst, 8) == 0);
1787        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1788        RegIndex vd;
1789        if (single) {
1790            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1791                                      bits(machInst, 22));
1792        } else {
1793            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1794                                      (bits(machInst, 22) << 5));
1795        }
1796        switch (bits(opcode, 4, 3)) {
1797          case 0x0:
1798            if (bits(opcode, 4, 1) == 0x2 &&
1799                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1800                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1801                if ((bits(machInst, 7, 4) & 0xd) != 1) {
1802                    break;
1803                }
1804                const IntRegIndex rt =
1805                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1806                const IntRegIndex rt2 =
1807                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1808                const bool op = bits(machInst, 20);
1809                uint32_t vm;
1810                if (single) {
1811                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1812                } else {
1813                    vm = (bits(machInst, 3, 0) << 1) |
1814                         (bits(machInst, 5) << 5);
1815                }
1816                if (op) {
1817                    return new Vmov2Core2Reg(machInst, rt, rt2,
1818                                             (IntRegIndex)vm);
1819                } else {
1820                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1821                                             rt, rt2);
1822                }
1823            }
1824            break;
1825          case 0x1:
1826            {
1827                if (offset == 0 || vd + offset/2 > NumFloatArchRegs) {
1828                    break;
1829                }
1830                switch (bits(opcode, 1, 0)) {
1831                  case 0x0:
1832                    return new VLdmStm(machInst, rn, vd, single,
1833                                       true, false, false, offset);
1834                  case 0x1:
1835                    return new VLdmStm(machInst, rn, vd, single,
1836                                       true, false, true, offset);
1837                  case 0x2:
1838                    return new VLdmStm(machInst, rn, vd, single,
1839                                       true, true, false, offset);
1840                  case 0x3:
1841                    // If rn == sp, then this is called vpop.
1842                    return new VLdmStm(machInst, rn, vd, single,
1843                                       true, true, true, offset);
1844                }
1845            }
1846          case 0x2:
1847            if (bits(opcode, 1, 0) == 0x2) {
1848                // If rn == sp, then this is called vpush.
1849                return new VLdmStm(machInst, rn, vd, single,
1850                                   false, true, false, offset);
1851            } else if (bits(opcode, 1, 0) == 0x3) {
1852                return new VLdmStm(machInst, rn, vd, single,
1853                                   false, true, true, offset);
1854            }
1855            // Fall through on purpose
1856          case 0x3:
1857            const bool up = (bits(machInst, 23) == 1);
1858            const uint32_t imm = bits(machInst, 7, 0) << 2;
1859            RegIndex vd;
1860            if (single) {
1861                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1862                                          (bits(machInst, 22)));
1863            } else {
1864                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1865                                          (bits(machInst, 22) << 5));
1866            }
1867            if (bits(opcode, 1, 0) == 0x0) {
1868                if (single) {
1869                    if (up) {
1870                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
1871                    } else {
1872                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
1873                    }
1874                } else {
1875                    if (up) {
1876                        return new %(vstr_ud)s(machInst, vd, vd + 1,
1877                                               rn, up, imm);
1878                    } else {
1879                        return new %(vstr_d)s(machInst, vd, vd + 1,
1880                                              rn, up, imm);
1881                    }
1882                }
1883            } else if (bits(opcode, 1, 0) == 0x1) {
1884                if (single) {
1885                    if (up) {
1886                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
1887                    } else {
1888                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
1889                    }
1890                } else {
1891                    if (up) {
1892                        return new %(vldr_ud)s(machInst, vd, vd + 1,
1893                                               rn, up, imm);
1894                    } else {
1895                        return new %(vldr_d)s(machInst, vd, vd + 1,
1896                                              rn, up, imm);
1897                    }
1898                }
1899            }
1900        }
1901        return new Unknown(machInst);
1902    }
1903    ''' % {
1904        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
1905        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
1906        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
1907        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
1908        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
1909        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
1910        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
1911        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
1912    }
1913}};
1914
1915def format ExtensionRegLoadStore() {{
1916    decode_block = '''
1917    return decodeExtensionRegLoadStore(machInst);
1918    '''
1919}};
1920
1921let {{
1922    header_output = '''
1923    StaticInstPtr
1924    decodeShortFpTransfer(ExtMachInst machInst);
1925    '''
1926    decoder_output = '''
1927    StaticInstPtr
1928    decodeShortFpTransfer(ExtMachInst machInst)
1929    {
1930        const uint32_t l = bits(machInst, 20);
1931        const uint32_t c = bits(machInst, 8);
1932        const uint32_t a = bits(machInst, 23, 21);
1933        const uint32_t b = bits(machInst, 6, 5);
1934        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1935            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
1936            return new Unknown(machInst);
1937        }
1938        if (l == 0 && c == 0) {
1939            if (a == 0) {
1940                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
1941                                    bits(machInst, 7);
1942                const IntRegIndex rt =
1943                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1944                if (bits(machInst, 20) == 1) {
1945                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
1946                } else {
1947                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
1948                }
1949            } else if (a == 0x7) {
1950                const IntRegIndex rt =
1951                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1952                uint32_t specReg = bits(machInst, 19, 16);
1953                switch (specReg) {
1954                  case 0:
1955                    specReg = MISCREG_FPSID;
1956                    break;
1957                  case 1:
1958                    specReg = MISCREG_FPSCR;
1959                    break;
1960                  case 6:
1961                    specReg = MISCREG_MVFR1;
1962                    break;
1963                  case 7:
1964                    specReg = MISCREG_MVFR0;
1965                    break;
1966                  case 8:
1967                    specReg = MISCREG_FPEXC;
1968                    break;
1969                  default:
1970                    return new Unknown(machInst);
1971                }
1972                if (specReg == MISCREG_FPSCR) {
1973                    return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
1974                } else {
1975                    return new Vmsr(machInst, (IntRegIndex)specReg, rt);
1976                }
1977            }
1978        } else if (l == 0 && c == 1) {
1979            if (bits(a, 2) == 0) {
1980                uint32_t vd = (bits(machInst, 7) << 5) |
1981                              (bits(machInst, 19, 16) << 1);
1982                // Handle accessing each single precision half of the vector.
1983                vd += bits(machInst, 21);
1984                const IntRegIndex rt =
1985                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1986                if (bits(machInst, 22) == 1) {
1987                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
1988                                            rt, bits(machInst, 6, 5));
1989                } else if (bits(machInst, 5) == 1) {
1990                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
1991                                            rt, bits(machInst, 6));
1992                } else if (bits(machInst, 6) == 0) {
1993                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
1994                } else {
1995                    return new Unknown(machInst);
1996                }
1997            } else if (bits(b, 1) == 0) {
1998                bool q = bits(machInst, 21);
1999                unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
2000                IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
2001                    (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
2002                IntRegIndex rt = (IntRegIndex)(uint32_t)
2003                    bits(machInst, 15, 12);
2004                if (q) {
2005                    switch (be) {
2006                      case 0:
2007                        return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2008                      case 1:
2009                        return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2010                      case 2:
2011                        return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2012                      case 3:
2013                        return new Unknown(machInst);
2014                    }
2015                } else {
2016                    switch (be) {
2017                      case 0:
2018                        return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2019                      case 1:
2020                        return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2021                      case 2:
2022                        return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2023                      case 3:
2024                        return new Unknown(machInst);
2025                    }
2026                }
2027            }
2028        } else if (l == 1 && c == 0) {
2029            if (a == 0) {
2030                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2031                                    bits(machInst, 7);
2032                const IntRegIndex rt =
2033                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2034                if (bits(machInst, 20) == 1) {
2035                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2036                } else {
2037                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2038                }
2039            } else if (a == 7) {
2040                const IntRegIndex rt =
2041                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2042                uint32_t specReg = bits(machInst, 19, 16);
2043                switch (specReg) {
2044                  case 0:
2045                    specReg = MISCREG_FPSID;
2046                    break;
2047                  case 1:
2048                    specReg = MISCREG_FPSCR;
2049                    break;
2050                  case 6:
2051                    specReg = MISCREG_MVFR1;
2052                    break;
2053                  case 7:
2054                    specReg = MISCREG_MVFR0;
2055                    break;
2056                  case 8:
2057                    specReg = MISCREG_FPEXC;
2058                    break;
2059                  default:
2060                    return new Unknown(machInst);
2061                }
2062                if (rt == 0xf) {
2063                    CPSR cpsrMask = 0;
2064                    cpsrMask.n = 1;
2065                    cpsrMask.z = 1;
2066                    cpsrMask.c = 1;
2067                    cpsrMask.v = 1;
2068                    if (specReg == MISCREG_FPSCR) {
2069                        return new VmrsApsrFpscr(machInst, INTREG_CONDCODES,
2070                                (IntRegIndex)specReg, (uint32_t)cpsrMask);
2071                    } else {
2072                        return new VmrsApsr(machInst, INTREG_CONDCODES,
2073                                (IntRegIndex)specReg, (uint32_t)cpsrMask);
2074                    }
2075                } else if (specReg == MISCREG_FPSCR) {
2076                    return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
2077                } else {
2078                    return new Vmrs(machInst, rt, (IntRegIndex)specReg);
2079                }
2080            }
2081        } else {
2082            uint32_t vd = (bits(machInst, 7) << 5) |
2083                          (bits(machInst, 19, 16) << 1);
2084            // Handle indexing into each single precision half of the vector.
2085            vd += bits(machInst, 21);
2086            uint32_t index;
2087            const IntRegIndex rt =
2088                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2089            const bool u = (bits(machInst, 23) == 1);
2090            if (bits(machInst, 22) == 1) {
2091                index = bits(machInst, 6, 5);
2092                if (u) {
2093                    return new VmovRegCoreUB(machInst, rt,
2094                                             (IntRegIndex)vd, index);
2095                } else {
2096                    return new VmovRegCoreSB(machInst, rt,
2097                                             (IntRegIndex)vd, index);
2098                }
2099            } else if (bits(machInst, 5) == 1) {
2100                index = bits(machInst, 6);
2101                if (u) {
2102                    return new VmovRegCoreUH(machInst, rt,
2103                                             (IntRegIndex)vd, index);
2104                } else {
2105                    return new VmovRegCoreSH(machInst, rt,
2106                                             (IntRegIndex)vd, index);
2107                }
2108            } else if (bits(machInst, 6) == 0 && !u) {
2109                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2110            } else {
2111                return new Unknown(machInst);
2112            }
2113        }
2114        return new Unknown(machInst);
2115    }
2116    '''
2117}};
2118
2119def format ShortFpTransfer() {{
2120    decode_block = '''
2121    return decodeShortFpTransfer(machInst);
2122    '''
2123}};
2124
2125let {{
2126    header_output = '''
2127    StaticInstPtr
2128    decodeVfpData(ExtMachInst machInst);
2129    '''
2130    decoder_output = '''
2131    StaticInstPtr
2132    decodeVfpData(ExtMachInst machInst)
2133    {
2134        const uint32_t opc1 = bits(machInst, 23, 20);
2135        const uint32_t opc2 = bits(machInst, 19, 16);
2136        const uint32_t opc3 = bits(machInst, 7, 6);
2137        //const uint32_t opc4 = bits(machInst, 3, 0);
2138        const bool single = (bits(machInst, 8) == 0);
2139        // Used to select between vcmp and vcmpe.
2140        const bool e = (bits(machInst, 7) == 1);
2141        IntRegIndex vd;
2142        IntRegIndex vm;
2143        IntRegIndex vn;
2144        if (single) {
2145            vd = (IntRegIndex)(bits(machInst, 22) |
2146                    (bits(machInst, 15, 12) << 1));
2147            vm = (IntRegIndex)(bits(machInst, 5) |
2148                    (bits(machInst, 3, 0) << 1));
2149            vn = (IntRegIndex)(bits(machInst, 7) |
2150                    (bits(machInst, 19, 16) << 1));
2151        } else {
2152            vd = (IntRegIndex)((bits(machInst, 22) << 5) |
2153                    (bits(machInst, 15, 12) << 1));
2154            vm = (IntRegIndex)((bits(machInst, 5) << 5) |
2155                    (bits(machInst, 3, 0) << 1));
2156            vn = (IntRegIndex)((bits(machInst, 7) << 5) |
2157                    (bits(machInst, 19, 16) << 1));
2158        }
2159        switch (opc1 & 0xb /* 1011 */) {
2160          case 0x0:
2161            if (bits(machInst, 6) == 0) {
2162                if (single) {
2163                    return decodeVfpRegRegRegOp<VmlaS>(
2164                            machInst, vd, vn, vm, false);
2165                } else {
2166                    return decodeVfpRegRegRegOp<VmlaD>(
2167                            machInst, vd, vn, vm, true);
2168                }
2169            } else {
2170                if (single) {
2171                    return decodeVfpRegRegRegOp<VmlsS>(
2172                            machInst, vd, vn, vm, false);
2173                } else {
2174                    return decodeVfpRegRegRegOp<VmlsD>(
2175                            machInst, vd, vn, vm, true);
2176                }
2177            }
2178          case 0x1:
2179            if (bits(machInst, 6) == 1) {
2180                if (single) {
2181                    return decodeVfpRegRegRegOp<VnmlaS>(
2182                            machInst, vd, vn, vm, false);
2183                } else {
2184                    return decodeVfpRegRegRegOp<VnmlaD>(
2185                            machInst, vd, vn, vm, true);
2186                }
2187            } else {
2188                if (single) {
2189                    return decodeVfpRegRegRegOp<VnmlsS>(
2190                            machInst, vd, vn, vm, false);
2191                } else {
2192                    return decodeVfpRegRegRegOp<VnmlsD>(
2193                            machInst, vd, vn, vm, true);
2194                }
2195            }
2196          case 0x2:
2197            if ((opc3 & 0x1) == 0) {
2198                if (single) {
2199                    return decodeVfpRegRegRegOp<VmulS>(
2200                            machInst, vd, vn, vm, false);
2201                } else {
2202                    return decodeVfpRegRegRegOp<VmulD>(
2203                            machInst, vd, vn, vm, true);
2204                }
2205            } else {
2206                if (single) {
2207                    return decodeVfpRegRegRegOp<VnmulS>(
2208                            machInst, vd, vn, vm, false);
2209                } else {
2210                    return decodeVfpRegRegRegOp<VnmulD>(
2211                            machInst, vd, vn, vm, true);
2212                }
2213            }
2214          case 0x3:
2215            if ((opc3 & 0x1) == 0) {
2216                if (single) {
2217                    return decodeVfpRegRegRegOp<VaddS>(
2218                            machInst, vd, vn, vm, false);
2219                } else {
2220                    return decodeVfpRegRegRegOp<VaddD>(
2221                            machInst, vd, vn, vm, true);
2222                }
2223            } else {
2224                if (single) {
2225                    return decodeVfpRegRegRegOp<VsubS>(
2226                            machInst, vd, vn, vm, false);
2227                } else {
2228                    return decodeVfpRegRegRegOp<VsubD>(
2229                            machInst, vd, vn, vm, true);
2230                }
2231            }
2232          case 0x8:
2233            if ((opc3 & 0x1) == 0) {
2234                if (single) {
2235                    return decodeVfpRegRegRegOp<VdivS>(
2236                            machInst, vd, vn, vm, false);
2237                } else {
2238                    return decodeVfpRegRegRegOp<VdivD>(
2239                            machInst, vd, vn, vm, true);
2240                }
2241            }
2242            break;
2243          case 0xb:
2244            if ((opc3 & 0x1) == 0) {
2245                const uint32_t baseImm =
2246                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
2247                if (single) {
2248                    uint32_t imm = vfp_modified_imm(baseImm, false);
2249                    return decodeVfpRegImmOp<VmovImmS>(
2250                            machInst, vd, imm, false);
2251                } else {
2252                    uint64_t imm = vfp_modified_imm(baseImm, true);
2253                    return decodeVfpRegImmOp<VmovImmD>(
2254                            machInst, vd, imm, true);
2255                }
2256            }
2257            switch (opc2) {
2258              case 0x0:
2259                if (opc3 == 1) {
2260                    if (single) {
2261                        return decodeVfpRegRegOp<VmovRegS>(
2262                                machInst, vd, vm, false);
2263                    } else {
2264                        return decodeVfpRegRegOp<VmovRegD>(
2265                                machInst, vd, vm, true);
2266                    }
2267                } else {
2268                    if (single) {
2269                        return decodeVfpRegRegOp<VabsS>(
2270                                machInst, vd, vm, false);
2271                    } else {
2272                        return decodeVfpRegRegOp<VabsD>(
2273                                machInst, vd, vm, true);
2274                    }
2275                }
2276              case 0x1:
2277                if (opc3 == 1) {
2278                    if (single) {
2279                        return decodeVfpRegRegOp<VnegS>(
2280                                machInst, vd, vm, false);
2281                    } else {
2282                        return decodeVfpRegRegOp<VnegD>(
2283                                machInst, vd, vm, true);
2284                    }
2285                } else {
2286                    if (single) {
2287                        return decodeVfpRegRegOp<VsqrtS>(
2288                                machInst, vd, vm, false);
2289                    } else {
2290                        return decodeVfpRegRegOp<VsqrtD>(
2291                                machInst, vd, vm, true);
2292                    }
2293                }
2294              case 0x2:
2295              case 0x3:
2296                {
2297                    const bool toHalf = bits(machInst, 16);
2298                    const bool top = bits(machInst, 7);
2299                    if (top) {
2300                        if (toHalf) {
2301                            return new VcvtFpSFpHT(machInst, vd, vm);
2302                        } else {
2303                            return new VcvtFpHTFpS(machInst, vd, vm);
2304                        }
2305                    } else {
2306                        if (toHalf) {
2307                            return new VcvtFpSFpHB(machInst, vd, vm);
2308                        } else {
2309                            return new VcvtFpHBFpS(machInst, vd, vm);
2310                        }
2311                    }
2312                }
2313              case 0x4:
2314                if (single) {
2315                    if (e) {
2316                        return new VcmpeS(machInst, vd, vm);
2317                    } else {
2318                        return new VcmpS(machInst, vd, vm);
2319                    }
2320                } else {
2321                    if (e) {
2322                        return new VcmpeD(machInst, vd, vm);
2323                    } else {
2324                        return new VcmpD(machInst, vd, vm);
2325                    }
2326                }
2327              case 0x5:
2328                if (single) {
2329                    if (e) {
2330                        return new VcmpeZeroS(machInst, vd, 0);
2331                    } else {
2332                        return new VcmpZeroS(machInst, vd, 0);
2333                    }
2334                } else {
2335                    if (e) {
2336                        return new VcmpeZeroD(machInst, vd, 0);
2337                    } else {
2338                        return new VcmpZeroD(machInst, vd, 0);
2339                    }
2340                }
2341              case 0x7:
2342                if (opc3 == 0x3) {
2343                    if (single) {
2344                        vm = (IntRegIndex)(bits(machInst, 5) |
2345                                (bits(machInst, 3, 0) << 1));
2346                        return new VcvtFpSFpD(machInst, vd, vm);
2347                    } else {
2348                        vd = (IntRegIndex)(bits(machInst, 22) |
2349                                (bits(machInst, 15, 12) << 1));
2350                        return new VcvtFpDFpS(machInst, vd, vm);
2351                    }
2352                }
2353                break;
2354              case 0x8:
2355                if (bits(machInst, 7) == 0) {
2356                    if (single) {
2357                        return new VcvtUIntFpS(machInst, vd, vm);
2358                    } else {
2359                        vm = (IntRegIndex)(bits(machInst, 5) |
2360                                (bits(machInst, 3, 0) << 1));
2361                        return new VcvtUIntFpD(machInst, vd, vm);
2362                    }
2363                } else {
2364                    if (single) {
2365                        return new VcvtSIntFpS(machInst, vd, vm);
2366                    } else {
2367                        vm = (IntRegIndex)(bits(machInst, 5) |
2368                                (bits(machInst, 3, 0) << 1));
2369                        return new VcvtSIntFpD(machInst, vd, vm);
2370                    }
2371                }
2372              case 0xa:
2373                {
2374                    const bool half = (bits(machInst, 7) == 0);
2375                    const uint32_t imm = bits(machInst, 5) |
2376                                         (bits(machInst, 3, 0) << 1);
2377                    const uint32_t size =
2378                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2379                    if (single) {
2380                        if (half) {
2381                            return new VcvtSHFixedFpS(machInst, vd, vd, size);
2382                        } else {
2383                            return new VcvtSFixedFpS(machInst, vd, vd, size);
2384                        }
2385                    } else {
2386                        if (half) {
2387                            return new VcvtSHFixedFpD(machInst, vd, vd, size);
2388                        } else {
2389                            return new VcvtSFixedFpD(machInst, vd, vd, size);
2390                        }
2391                    }
2392                }
2393              case 0xb:
2394                {
2395                    const bool half = (bits(machInst, 7) == 0);
2396                    const uint32_t imm = bits(machInst, 5) |
2397                                         (bits(machInst, 3, 0) << 1);
2398                    const uint32_t size =
2399                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2400                    if (single) {
2401                        if (half) {
2402                            return new VcvtUHFixedFpS(machInst, vd, vd, size);
2403                        } else {
2404                            return new VcvtUFixedFpS(machInst, vd, vd, size);
2405                        }
2406                    } else {
2407                        if (half) {
2408                            return new VcvtUHFixedFpD(machInst, vd, vd, size);
2409                        } else {
2410                            return new VcvtUFixedFpD(machInst, vd, vd, size);
2411                        }
2412                    }
2413                }
2414              case 0xc:
2415                if (bits(machInst, 7) == 0) {
2416                    if (single) {
2417                        return new VcvtFpUIntSR(machInst, vd, vm);
2418                    } else {
2419                        vd = (IntRegIndex)(bits(machInst, 22) |
2420                                (bits(machInst, 15, 12) << 1));
2421                        return new VcvtFpUIntDR(machInst, vd, vm);
2422                    }
2423                } else {
2424                    if (single) {
2425                        return new VcvtFpUIntS(machInst, vd, vm);
2426                    } else {
2427                        vd = (IntRegIndex)(bits(machInst, 22) |
2428                                (bits(machInst, 15, 12) << 1));
2429                        return new VcvtFpUIntD(machInst, vd, vm);
2430                    }
2431                }
2432              case 0xd:
2433                if (bits(machInst, 7) == 0) {
2434                    if (single) {
2435                        return new VcvtFpSIntSR(machInst, vd, vm);
2436                    } else {
2437                        vd = (IntRegIndex)(bits(machInst, 22) |
2438                                (bits(machInst, 15, 12) << 1));
2439                        return new VcvtFpSIntDR(machInst, vd, vm);
2440                    }
2441                } else {
2442                    if (single) {
2443                        return new VcvtFpSIntS(machInst, vd, vm);
2444                    } else {
2445                        vd = (IntRegIndex)(bits(machInst, 22) |
2446                                (bits(machInst, 15, 12) << 1));
2447                        return new VcvtFpSIntD(machInst, vd, vm);
2448                    }
2449                }
2450              case 0xe:
2451                {
2452                    const bool half = (bits(machInst, 7) == 0);
2453                    const uint32_t imm = bits(machInst, 5) |
2454                                         (bits(machInst, 3, 0) << 1);
2455                    const uint32_t size =
2456                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2457                    if (single) {
2458                        if (half) {
2459                            return new VcvtFpSHFixedS(machInst, vd, vd, size);
2460                        } else {
2461                            return new VcvtFpSFixedS(machInst, vd, vd, size);
2462                        }
2463                    } else {
2464                        if (half) {
2465                            return new VcvtFpSHFixedD(machInst, vd, vd, size);
2466                        } else {
2467                            return new VcvtFpSFixedD(machInst, vd, vd, size);
2468                        }
2469                    }
2470                }
2471              case 0xf:
2472                {
2473                    const bool half = (bits(machInst, 7) == 0);
2474                    const uint32_t imm = bits(machInst, 5) |
2475                                         (bits(machInst, 3, 0) << 1);
2476                    const uint32_t size =
2477                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
2478                    if (single) {
2479                        if (half) {
2480                            return new VcvtFpUHFixedS(machInst, vd, vd, size);
2481                        } else {
2482                            return new VcvtFpUFixedS(machInst, vd, vd, size);
2483                        }
2484                    } else {
2485                        if (half) {
2486                            return new VcvtFpUHFixedD(machInst, vd, vd, size);
2487                        } else {
2488                            return new VcvtFpUFixedD(machInst, vd, vd, size);
2489                        }
2490                    }
2491                }
2492            }
2493            break;
2494        }
2495        return new Unknown(machInst);
2496    }
2497    '''
2498}};
2499
2500def format VfpData() {{
2501    decode_block = '''
2502    return decodeVfpData(machInst);
2503    '''
2504}};
2505