fp.isa revision 7337
16019Shines@cs.fsu.edu// -*- mode:c++ -*-
26019Shines@cs.fsu.edu
37178Sgblack@eecs.umich.edu// Copyright (c) 2010 ARM Limited
47178Sgblack@eecs.umich.edu// All rights reserved
57178Sgblack@eecs.umich.edu//
67178Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall
77178Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual
87178Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating
97178Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software
107178Sgblack@eecs.umich.edu// licensed hereunder.  You may use the software subject to the license
117178Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated
127178Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software,
137178Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form.
147178Sgblack@eecs.umich.edu//
156019Shines@cs.fsu.edu// Copyright (c) 2007-2008 The Florida State University
166019Shines@cs.fsu.edu// All rights reserved.
176019Shines@cs.fsu.edu//
186019Shines@cs.fsu.edu// Redistribution and use in source and binary forms, with or without
196019Shines@cs.fsu.edu// modification, are permitted provided that the following conditions are
206019Shines@cs.fsu.edu// met: redistributions of source code must retain the above copyright
216019Shines@cs.fsu.edu// notice, this list of conditions and the following disclaimer;
226019Shines@cs.fsu.edu// redistributions in binary form must reproduce the above copyright
236019Shines@cs.fsu.edu// notice, this list of conditions and the following disclaimer in the
246019Shines@cs.fsu.edu// documentation and/or other materials provided with the distribution;
256019Shines@cs.fsu.edu// neither the name of the copyright holders nor the names of its
266019Shines@cs.fsu.edu// contributors may be used to endorse or promote products derived from
276019Shines@cs.fsu.edu// this software without specific prior written permission.
286019Shines@cs.fsu.edu//
296019Shines@cs.fsu.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
306019Shines@cs.fsu.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
316019Shines@cs.fsu.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
326019Shines@cs.fsu.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
336019Shines@cs.fsu.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
346019Shines@cs.fsu.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
356019Shines@cs.fsu.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
366019Shines@cs.fsu.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
376019Shines@cs.fsu.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
386019Shines@cs.fsu.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
396019Shines@cs.fsu.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
406019Shines@cs.fsu.edu//
416019Shines@cs.fsu.edu// Authors: Stephen Hines
426019Shines@cs.fsu.edu
436019Shines@cs.fsu.edu////////////////////////////////////////////////////////////////////
446019Shines@cs.fsu.edu//
456019Shines@cs.fsu.edu// Floating Point operate instructions
466019Shines@cs.fsu.edu//
476019Shines@cs.fsu.edu
486019Shines@cs.fsu.edudef template FPAExecute {{
496019Shines@cs.fsu.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
506019Shines@cs.fsu.edu        {
516019Shines@cs.fsu.edu                Fault fault = NoFault;
526019Shines@cs.fsu.edu
536019Shines@cs.fsu.edu                %(fp_enable_check)s;
546019Shines@cs.fsu.edu
556019Shines@cs.fsu.edu                %(op_decl)s;
566019Shines@cs.fsu.edu                %(op_rd)s;
576019Shines@cs.fsu.edu
586243Sgblack@eecs.umich.edu                if (%(predicate_test)s) {
596243Sgblack@eecs.umich.edu                    %(code)s;
606243Sgblack@eecs.umich.edu                    if (fault == NoFault) {
616243Sgblack@eecs.umich.edu                        %(op_wb)s;
626243Sgblack@eecs.umich.edu                    }
636019Shines@cs.fsu.edu                }
646019Shines@cs.fsu.edu
656019Shines@cs.fsu.edu                return fault;
666019Shines@cs.fsu.edu        }
676019Shines@cs.fsu.edu}};
686019Shines@cs.fsu.edu
696019Shines@cs.fsu.edudef template FloatDoubleDecode {{
706019Shines@cs.fsu.edu    {
716019Shines@cs.fsu.edu        ArmStaticInst *i = NULL;
726019Shines@cs.fsu.edu        switch (OPCODE_19 << 1 | OPCODE_7)
736019Shines@cs.fsu.edu        {
746019Shines@cs.fsu.edu            case 0:
756019Shines@cs.fsu.edu                i = (ArmStaticInst *)new %(class_name)sS(machInst);
766019Shines@cs.fsu.edu                break;
776019Shines@cs.fsu.edu            case 1:
786019Shines@cs.fsu.edu                i = (ArmStaticInst *)new %(class_name)sD(machInst);
796019Shines@cs.fsu.edu                break;
806019Shines@cs.fsu.edu            case 2:
816019Shines@cs.fsu.edu            case 3:
826019Shines@cs.fsu.edu            default:
836019Shines@cs.fsu.edu                panic("Cannot decode float/double nature of the instruction");
846019Shines@cs.fsu.edu        }
856019Shines@cs.fsu.edu        return i;
866019Shines@cs.fsu.edu    }
876019Shines@cs.fsu.edu}};
886019Shines@cs.fsu.edu
896019Shines@cs.fsu.edu// Primary format for float point operate instructions:
906019Shines@cs.fsu.edudef format FloatOp(code, *flags) {{
916019Shines@cs.fsu.edu        orig_code = code
926019Shines@cs.fsu.edu
936019Shines@cs.fsu.edu        cblk = code
946252Sgblack@eecs.umich.edu        iop = InstObjParams(name, Name, 'PredOp',
956243Sgblack@eecs.umich.edu                            {"code": cblk,
966243Sgblack@eecs.umich.edu                             "predicate_test": predicateTest},
976243Sgblack@eecs.umich.edu                            flags)
986019Shines@cs.fsu.edu        header_output = BasicDeclare.subst(iop)
996019Shines@cs.fsu.edu        decoder_output = BasicConstructor.subst(iop)
1006019Shines@cs.fsu.edu        exec_output = FPAExecute.subst(iop)
1016019Shines@cs.fsu.edu
1026019Shines@cs.fsu.edu        sng_cblk = code
1036252Sgblack@eecs.umich.edu        sng_iop = InstObjParams(name, Name+'S', 'PredOp',
1046243Sgblack@eecs.umich.edu                                {"code": sng_cblk,
1056243Sgblack@eecs.umich.edu                                 "predicate_test": predicateTest},
1066243Sgblack@eecs.umich.edu                                flags)
1076019Shines@cs.fsu.edu        header_output += BasicDeclare.subst(sng_iop)
1086019Shines@cs.fsu.edu        decoder_output += BasicConstructor.subst(sng_iop)
1096019Shines@cs.fsu.edu        exec_output += FPAExecute.subst(sng_iop)
1106019Shines@cs.fsu.edu
1116019Shines@cs.fsu.edu        dbl_code = re.sub(r'\.sf', '.df', orig_code)
1126019Shines@cs.fsu.edu
1136019Shines@cs.fsu.edu        dbl_cblk = dbl_code
1146252Sgblack@eecs.umich.edu        dbl_iop = InstObjParams(name, Name+'D', 'PredOp',
1156243Sgblack@eecs.umich.edu                                {"code": dbl_cblk,
1166243Sgblack@eecs.umich.edu                                 "predicate_test": predicateTest},
1176243Sgblack@eecs.umich.edu                                flags)
1186019Shines@cs.fsu.edu        header_output += BasicDeclare.subst(dbl_iop)
1196019Shines@cs.fsu.edu        decoder_output += BasicConstructor.subst(dbl_iop)
1206019Shines@cs.fsu.edu        exec_output += FPAExecute.subst(dbl_iop)
1216019Shines@cs.fsu.edu
1226019Shines@cs.fsu.edu        decode_block = FloatDoubleDecode.subst(iop)
1236019Shines@cs.fsu.edu}};
1246019Shines@cs.fsu.edu
1256019Shines@cs.fsu.edulet {{
1266019Shines@cs.fsu.edu        calcFPCcCode = '''
1276019Shines@cs.fsu.edu        uint16_t _in, _iz, _ic, _iv;
1286019Shines@cs.fsu.edu
1296019Shines@cs.fsu.edu        _in = %(fReg1)s < %(fReg2)s;
1306019Shines@cs.fsu.edu        _iz = %(fReg1)s == %(fReg2)s;
1316019Shines@cs.fsu.edu        _ic = %(fReg1)s >= %(fReg2)s;
1326019Shines@cs.fsu.edu        _iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
1336019Shines@cs.fsu.edu
1346724Sgblack@eecs.umich.edu        CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
1356724Sgblack@eecs.umich.edu            (CondCodes & 0x0FFFFFFF);
1366019Shines@cs.fsu.edu        '''
1376019Shines@cs.fsu.edu}};
1386019Shines@cs.fsu.edu
1396019Shines@cs.fsu.edudef format FloatCmp(fReg1, fReg2, *flags) {{
1406019Shines@cs.fsu.edu        code = calcFPCcCode % vars()
1416252Sgblack@eecs.umich.edu        iop = InstObjParams(name, Name, 'PredOp',
1426243Sgblack@eecs.umich.edu                            {"code": code,
1436243Sgblack@eecs.umich.edu                             "predicate_test": predicateTest},
1446243Sgblack@eecs.umich.edu                             flags)
1456019Shines@cs.fsu.edu        header_output = BasicDeclare.subst(iop)
1466019Shines@cs.fsu.edu        decoder_output = BasicConstructor.subst(iop)
1476019Shines@cs.fsu.edu        decode_block = BasicDecode.subst(iop)
1486019Shines@cs.fsu.edu        exec_output = FPAExecute.subst(iop)
1496019Shines@cs.fsu.edu}};
1506019Shines@cs.fsu.edu
1517178Sgblack@eecs.umich.edudef format ExtensionRegLoadStore() {{
1527178Sgblack@eecs.umich.edu    decode_block = '''
1537178Sgblack@eecs.umich.edu    {
1547178Sgblack@eecs.umich.edu        const uint32_t opcode = bits(machInst, 24, 20);
1557178Sgblack@eecs.umich.edu        const uint32_t offset = bits(machInst, 7, 0);
1567337Sgblack@eecs.umich.edu        const bool single = (bits(machInst, 8) == 0);
1577178Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1587178Sgblack@eecs.umich.edu        RegIndex vd;
1597178Sgblack@eecs.umich.edu        if (single) {
1607178Sgblack@eecs.umich.edu            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1617178Sgblack@eecs.umich.edu                                      bits(machInst, 22));
1627178Sgblack@eecs.umich.edu        } else {
1637178Sgblack@eecs.umich.edu            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1647178Sgblack@eecs.umich.edu                                      (bits(machInst, 22) << 5));
1657178Sgblack@eecs.umich.edu        }
1667178Sgblack@eecs.umich.edu        switch (bits(opcode, 4, 3)) {
1677178Sgblack@eecs.umich.edu          case 0x0:
1687335Sgblack@eecs.umich.edu            if (bits(opcode, 4, 1) == 0x2 &&
1697335Sgblack@eecs.umich.edu                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1707335Sgblack@eecs.umich.edu                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1717335Sgblack@eecs.umich.edu                if ((bits(machInst, 7, 4) & 0xd) != 1) {
1727335Sgblack@eecs.umich.edu                    break;
1737335Sgblack@eecs.umich.edu                }
1747335Sgblack@eecs.umich.edu                const IntRegIndex rt =
1757335Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1767335Sgblack@eecs.umich.edu                const IntRegIndex rt2 =
1777335Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1787335Sgblack@eecs.umich.edu                const bool op = bits(machInst, 20);
1797335Sgblack@eecs.umich.edu                uint32_t vm;
1807337Sgblack@eecs.umich.edu                if (single) {
1817335Sgblack@eecs.umich.edu                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1827335Sgblack@eecs.umich.edu                } else {
1837335Sgblack@eecs.umich.edu                    vm = (bits(machInst, 3, 0) << 1) |
1847335Sgblack@eecs.umich.edu                         (bits(machInst, 5) << 5);
1857335Sgblack@eecs.umich.edu                }
1867335Sgblack@eecs.umich.edu                if (op) {
1877335Sgblack@eecs.umich.edu                    return new Vmov2Core2Reg(machInst, rt, rt2,
1887335Sgblack@eecs.umich.edu                                             (IntRegIndex)vm);
1897335Sgblack@eecs.umich.edu                } else {
1907335Sgblack@eecs.umich.edu                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1917335Sgblack@eecs.umich.edu                                             rt, rt2);
1927335Sgblack@eecs.umich.edu                }
1937178Sgblack@eecs.umich.edu            }
1947178Sgblack@eecs.umich.edu            break;
1957178Sgblack@eecs.umich.edu          case 0x1:
1967178Sgblack@eecs.umich.edu            switch (bits(opcode, 1, 0)) {
1977178Sgblack@eecs.umich.edu              case 0x0:
1987178Sgblack@eecs.umich.edu                return new VLdmStm(machInst, rn, vd, single,
1997178Sgblack@eecs.umich.edu                                   true, false, false, offset);
2007178Sgblack@eecs.umich.edu              case 0x1:
2017178Sgblack@eecs.umich.edu                return new VLdmStm(machInst, rn, vd, single,
2027178Sgblack@eecs.umich.edu                                   true, false, true, offset);
2037178Sgblack@eecs.umich.edu              case 0x2:
2047178Sgblack@eecs.umich.edu                return new VLdmStm(machInst, rn, vd, single,
2057178Sgblack@eecs.umich.edu                                   true, true, false, offset);
2067178Sgblack@eecs.umich.edu              case 0x3:
2077178Sgblack@eecs.umich.edu                // If rn == sp, then this is called vpop.
2087178Sgblack@eecs.umich.edu                return new VLdmStm(machInst, rn, vd, single,
2097178Sgblack@eecs.umich.edu                                   true, true, true, offset);
2107178Sgblack@eecs.umich.edu            }
2117178Sgblack@eecs.umich.edu          case 0x2:
2127178Sgblack@eecs.umich.edu            if (bits(opcode, 1, 0) == 0x2) {
2137178Sgblack@eecs.umich.edu                // If rn == sp, then this is called vpush.
2147178Sgblack@eecs.umich.edu                return new VLdmStm(machInst, rn, vd, single,
2157178Sgblack@eecs.umich.edu                                   false, true, false, offset);
2167178Sgblack@eecs.umich.edu            } else if (bits(opcode, 1, 0) == 0x3) {
2177178Sgblack@eecs.umich.edu                return new VLdmStm(machInst, rn, vd, single,
2187178Sgblack@eecs.umich.edu                                   false, true, true, offset);
2197178Sgblack@eecs.umich.edu            }
2207178Sgblack@eecs.umich.edu            // Fall through on purpose
2217178Sgblack@eecs.umich.edu          case 0x3:
2227178Sgblack@eecs.umich.edu            if (bits(opcode, 1, 0) == 0x0) {
2237178Sgblack@eecs.umich.edu                return new WarnUnimplemented("vstr", machInst);
2247178Sgblack@eecs.umich.edu            } else if (bits(opcode, 1, 0) == 0x1) {
2257337Sgblack@eecs.umich.edu                const bool up = (bits(machInst, 23) == 1);
2267337Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) << 2;
2277337Sgblack@eecs.umich.edu                RegIndex vd;
2287337Sgblack@eecs.umich.edu                if (single) {
2297337Sgblack@eecs.umich.edu                    vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
2307337Sgblack@eecs.umich.edu                                              (bits(machInst, 22)));
2317337Sgblack@eecs.umich.edu                    if (up) {
2327337Sgblack@eecs.umich.edu                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
2337337Sgblack@eecs.umich.edu                    } else {
2347337Sgblack@eecs.umich.edu                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
2357337Sgblack@eecs.umich.edu                    }
2367337Sgblack@eecs.umich.edu                } else {
2377337Sgblack@eecs.umich.edu                    vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
2387337Sgblack@eecs.umich.edu                                              (bits(machInst, 22) << 5));
2397337Sgblack@eecs.umich.edu                    if (up) {
2407337Sgblack@eecs.umich.edu                        return new %(vldr_ud)s(machInst, vd, vd + 1,
2417337Sgblack@eecs.umich.edu                                               rn, up, imm);
2427337Sgblack@eecs.umich.edu                    } else {
2437337Sgblack@eecs.umich.edu                        return new %(vldr_d)s(machInst, vd, vd + 1,
2447337Sgblack@eecs.umich.edu                                              rn, up, imm);
2457337Sgblack@eecs.umich.edu                    }
2467337Sgblack@eecs.umich.edu                }
2477178Sgblack@eecs.umich.edu            }
2487178Sgblack@eecs.umich.edu        }
2497178Sgblack@eecs.umich.edu        return new Unknown(machInst);
2507178Sgblack@eecs.umich.edu    }
2517337Sgblack@eecs.umich.edu    ''' % {
2527337Sgblack@eecs.umich.edu        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
2537337Sgblack@eecs.umich.edu        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
2547337Sgblack@eecs.umich.edu        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
2557337Sgblack@eecs.umich.edu        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False)
2567337Sgblack@eecs.umich.edu    }
2577178Sgblack@eecs.umich.edu}};
2587321Sgblack@eecs.umich.edu
2597321Sgblack@eecs.umich.edudef format ShortFpTransfer() {{
2607321Sgblack@eecs.umich.edu    decode_block = '''
2617321Sgblack@eecs.umich.edu    {
2627321Sgblack@eecs.umich.edu        const uint32_t l = bits(machInst, 20);
2637321Sgblack@eecs.umich.edu        const uint32_t c = bits(machInst, 8);
2647321Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 23, 21);
2657321Sgblack@eecs.umich.edu        const uint32_t b = bits(machInst, 6, 5);
2667321Sgblack@eecs.umich.edu        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
2677321Sgblack@eecs.umich.edu            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
2687321Sgblack@eecs.umich.edu            return new Unknown(machInst);
2697321Sgblack@eecs.umich.edu        }
2707321Sgblack@eecs.umich.edu        if (l == 0 && c == 0) {
2717321Sgblack@eecs.umich.edu            if (a == 0) {
2727335Sgblack@eecs.umich.edu                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2737335Sgblack@eecs.umich.edu                                    bits(machInst, 7);
2747335Sgblack@eecs.umich.edu                const IntRegIndex rt =
2757335Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2767335Sgblack@eecs.umich.edu                if (bits(machInst, 20) == 1) {
2777335Sgblack@eecs.umich.edu                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
2787335Sgblack@eecs.umich.edu                } else {
2797335Sgblack@eecs.umich.edu                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
2807335Sgblack@eecs.umich.edu                }
2817321Sgblack@eecs.umich.edu            } else if (a == 0x7) {
2827323Sgblack@eecs.umich.edu                const IntRegIndex rt =
2837323Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2847323Sgblack@eecs.umich.edu                uint32_t specReg = bits(machInst, 19, 16);
2857323Sgblack@eecs.umich.edu                switch (specReg) {
2867323Sgblack@eecs.umich.edu                  case 0:
2877323Sgblack@eecs.umich.edu                    specReg = MISCREG_FPSID;
2887323Sgblack@eecs.umich.edu                    break;
2897323Sgblack@eecs.umich.edu                  case 1:
2907323Sgblack@eecs.umich.edu                    specReg = MISCREG_FPSCR;
2917323Sgblack@eecs.umich.edu                    break;
2927323Sgblack@eecs.umich.edu                  case 8:
2937323Sgblack@eecs.umich.edu                    specReg = MISCREG_FPEXC;
2947323Sgblack@eecs.umich.edu                    break;
2957323Sgblack@eecs.umich.edu                  default:
2967323Sgblack@eecs.umich.edu                    return new Unknown(machInst);
2977323Sgblack@eecs.umich.edu                }
2987323Sgblack@eecs.umich.edu                return new Vmsr(machInst, (IntRegIndex)specReg, rt);
2997321Sgblack@eecs.umich.edu            }
3007321Sgblack@eecs.umich.edu        } else if (l == 0 && c == 1) {
3017321Sgblack@eecs.umich.edu            if (bits(a, 2) == 0) {
3027335Sgblack@eecs.umich.edu                uint32_t vd = (bits(machInst, 7) << 5) |
3037335Sgblack@eecs.umich.edu                              (bits(machInst, 19, 16) << 1);
3047335Sgblack@eecs.umich.edu                uint32_t index, size;
3057335Sgblack@eecs.umich.edu                const IntRegIndex rt =
3067335Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3077335Sgblack@eecs.umich.edu                if (bits(machInst, 22) == 1) {
3087335Sgblack@eecs.umich.edu                    size = 8;
3097335Sgblack@eecs.umich.edu                    index = (bits(machInst, 21) << 2) |
3107335Sgblack@eecs.umich.edu                            bits(machInst, 6, 5);
3117335Sgblack@eecs.umich.edu                } else if (bits(machInst, 5) == 1) {
3127335Sgblack@eecs.umich.edu                    size = 16;
3137335Sgblack@eecs.umich.edu                    index = (bits(machInst, 21) << 1) |
3147335Sgblack@eecs.umich.edu                            bits(machInst, 6);
3157335Sgblack@eecs.umich.edu                } else if (bits(machInst, 6) == 0) {
3167335Sgblack@eecs.umich.edu                    size = 32;
3177335Sgblack@eecs.umich.edu                    index = bits(machInst, 21);
3187335Sgblack@eecs.umich.edu                } else {
3197335Sgblack@eecs.umich.edu                    return new Unknown(machInst);
3207335Sgblack@eecs.umich.edu                }
3217335Sgblack@eecs.umich.edu                if (index >= (32 / size)) {
3227335Sgblack@eecs.umich.edu                    index -= (32 / size);
3237335Sgblack@eecs.umich.edu                    vd++;
3247335Sgblack@eecs.umich.edu                }
3257335Sgblack@eecs.umich.edu                switch (size) {
3267335Sgblack@eecs.umich.edu                  case 8:
3277335Sgblack@eecs.umich.edu                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
3287335Sgblack@eecs.umich.edu                                            rt, index);
3297335Sgblack@eecs.umich.edu                  case 16:
3307335Sgblack@eecs.umich.edu                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
3317335Sgblack@eecs.umich.edu                                            rt, index);
3327335Sgblack@eecs.umich.edu                  case 32:
3337335Sgblack@eecs.umich.edu                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
3347335Sgblack@eecs.umich.edu                }
3357321Sgblack@eecs.umich.edu            } else if (bits(b, 1) == 0) {
3367321Sgblack@eecs.umich.edu                // A8-594
3377321Sgblack@eecs.umich.edu                return new WarnUnimplemented("vdup", machInst);
3387321Sgblack@eecs.umich.edu            }
3397321Sgblack@eecs.umich.edu        } else if (l == 1 && c == 0) {
3407321Sgblack@eecs.umich.edu            if (a == 0) {
3417335Sgblack@eecs.umich.edu                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
3427335Sgblack@eecs.umich.edu                                    bits(machInst, 7);
3437335Sgblack@eecs.umich.edu                const IntRegIndex rt =
3447335Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3457335Sgblack@eecs.umich.edu                if (bits(machInst, 20) == 1) {
3467335Sgblack@eecs.umich.edu                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
3477335Sgblack@eecs.umich.edu                } else {
3487335Sgblack@eecs.umich.edu                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
3497335Sgblack@eecs.umich.edu                }
3507321Sgblack@eecs.umich.edu            } else if (a == 7) {
3517326Sgblack@eecs.umich.edu                const IntRegIndex rt =
3527326Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3537326Sgblack@eecs.umich.edu                uint32_t specReg = bits(machInst, 19, 16);
3547326Sgblack@eecs.umich.edu                switch (specReg) {
3557326Sgblack@eecs.umich.edu                  case 0:
3567326Sgblack@eecs.umich.edu                    specReg = MISCREG_FPSID;
3577326Sgblack@eecs.umich.edu                    break;
3587326Sgblack@eecs.umich.edu                  case 1:
3597326Sgblack@eecs.umich.edu                    specReg = MISCREG_FPSCR;
3607326Sgblack@eecs.umich.edu                    break;
3617326Sgblack@eecs.umich.edu                  case 6:
3627326Sgblack@eecs.umich.edu                    specReg = MISCREG_MVFR1;
3637326Sgblack@eecs.umich.edu                    break;
3647326Sgblack@eecs.umich.edu                  case 7:
3657326Sgblack@eecs.umich.edu                    specReg = MISCREG_MVFR0;
3667326Sgblack@eecs.umich.edu                    break;
3677326Sgblack@eecs.umich.edu                  case 8:
3687326Sgblack@eecs.umich.edu                    specReg = MISCREG_FPEXC;
3697326Sgblack@eecs.umich.edu                    break;
3707326Sgblack@eecs.umich.edu                  default:
3717326Sgblack@eecs.umich.edu                    return new Unknown(machInst);
3727326Sgblack@eecs.umich.edu                }
3737326Sgblack@eecs.umich.edu                return new Vmrs(machInst, rt, (IntRegIndex)specReg);
3747321Sgblack@eecs.umich.edu            }
3757321Sgblack@eecs.umich.edu        } else {
3767335Sgblack@eecs.umich.edu            uint32_t vd = (bits(machInst, 7) << 5) |
3777335Sgblack@eecs.umich.edu                          (bits(machInst, 19, 16) << 1);
3787335Sgblack@eecs.umich.edu            uint32_t index, size;
3797335Sgblack@eecs.umich.edu            const IntRegIndex rt =
3807335Sgblack@eecs.umich.edu                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3817335Sgblack@eecs.umich.edu            const bool u = (bits(machInst, 23) == 1);
3827335Sgblack@eecs.umich.edu            if (bits(machInst, 22) == 1) {
3837335Sgblack@eecs.umich.edu                size = 8;
3847335Sgblack@eecs.umich.edu                index = (bits(machInst, 21) << 2) |
3857335Sgblack@eecs.umich.edu                        bits(machInst, 6, 5);
3867335Sgblack@eecs.umich.edu            } else if (bits(machInst, 5) == 1) {
3877335Sgblack@eecs.umich.edu                size = 16;
3887335Sgblack@eecs.umich.edu                index = (bits(machInst, 21) << 1) |
3897335Sgblack@eecs.umich.edu                        bits(machInst, 6);
3907335Sgblack@eecs.umich.edu            } else if (bits(machInst, 6) == 0 && !u) {
3917335Sgblack@eecs.umich.edu                size = 32;
3927335Sgblack@eecs.umich.edu                index = bits(machInst, 21);
3937335Sgblack@eecs.umich.edu            } else {
3947335Sgblack@eecs.umich.edu                return new Unknown(machInst);
3957335Sgblack@eecs.umich.edu            }
3967335Sgblack@eecs.umich.edu            if (index >= (32 / size)) {
3977335Sgblack@eecs.umich.edu                index -= (32 / size);
3987335Sgblack@eecs.umich.edu                vd++;
3997335Sgblack@eecs.umich.edu            }
4007335Sgblack@eecs.umich.edu            switch (size) {
4017335Sgblack@eecs.umich.edu              case 8:
4027335Sgblack@eecs.umich.edu                if (u) {
4037335Sgblack@eecs.umich.edu                    return new VmovRegCoreUB(machInst, rt,
4047335Sgblack@eecs.umich.edu                                             (IntRegIndex)vd, index);
4057335Sgblack@eecs.umich.edu                } else {
4067335Sgblack@eecs.umich.edu                    return new VmovRegCoreSB(machInst, rt,
4077335Sgblack@eecs.umich.edu                                             (IntRegIndex)vd, index);
4087335Sgblack@eecs.umich.edu                }
4097335Sgblack@eecs.umich.edu              case 16:
4107335Sgblack@eecs.umich.edu                if (u) {
4117335Sgblack@eecs.umich.edu                    return new VmovRegCoreUH(machInst, rt,
4127335Sgblack@eecs.umich.edu                                             (IntRegIndex)vd, index);
4137335Sgblack@eecs.umich.edu                } else {
4147335Sgblack@eecs.umich.edu                    return new VmovRegCoreSH(machInst, rt,
4157335Sgblack@eecs.umich.edu                                             (IntRegIndex)vd, index);
4167335Sgblack@eecs.umich.edu                }
4177335Sgblack@eecs.umich.edu              case 32:
4187335Sgblack@eecs.umich.edu                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
4197335Sgblack@eecs.umich.edu            }
4207321Sgblack@eecs.umich.edu        }
4217321Sgblack@eecs.umich.edu        return new Unknown(machInst);
4227321Sgblack@eecs.umich.edu    }
4237321Sgblack@eecs.umich.edu    '''
4247321Sgblack@eecs.umich.edu}};
425