fp.isa revision 7367
12292SN/A// -*- mode:c++ -*-
210333Smitch.hayenga@arm.com
310239Sbinhpham@cs.rutgers.edu// Copyright (c) 2010 ARM Limited
48707Sandreas.hansson@arm.com// All rights reserved
58707Sandreas.hansson@arm.com//
68707Sandreas.hansson@arm.com// The license below extends only to copyright in the software and shall
78707Sandreas.hansson@arm.com// not be construed as granting a license to any other intellectual
88707Sandreas.hansson@arm.com// property including but not limited to intellectual property relating
98707Sandreas.hansson@arm.com// to a hardware implementation of the functionality of the software
108707Sandreas.hansson@arm.com// licensed hereunder.  You may use the software subject to the license
118707Sandreas.hansson@arm.com// terms below provided that you ensure that this notice is replicated
128707Sandreas.hansson@arm.com// unmodified and in its entirety in all distributions of the software,
138707Sandreas.hansson@arm.com// modified or unmodified, in source code or in binary form.
148707Sandreas.hansson@arm.com//
152727Sktlim@umich.edu// Copyright (c) 2007-2008 The Florida State University
162292SN/A// All rights reserved.
172292SN/A//
182292SN/A// Redistribution and use in source and binary forms, with or without
192292SN/A// modification, are permitted provided that the following conditions are
202292SN/A// met: redistributions of source code must retain the above copyright
212292SN/A// notice, this list of conditions and the following disclaimer;
222292SN/A// redistributions in binary form must reproduce the above copyright
232292SN/A// notice, this list of conditions and the following disclaimer in the
242292SN/A// documentation and/or other materials provided with the distribution;
252292SN/A// neither the name of the copyright holders nor the names of its
262292SN/A// contributors may be used to endorse or promote products derived from
272292SN/A// this software without specific prior written permission.
282292SN/A//
292292SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302292SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312292SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322292SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332292SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342292SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352292SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362292SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372292SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382292SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392292SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402689Sktlim@umich.edu//
412689Sktlim@umich.edu// Authors: Stephen Hines
422292SN/A
432292SN/A////////////////////////////////////////////////////////////////////
449944Smatt.horsnell@ARM.com//
459944Smatt.horsnell@ARM.com// Floating Point operate instructions
469944Smatt.horsnell@ARM.com//
472329SN/A
482980Sgblack@eecs.umich.edudef template FPAExecute {{
492329SN/A        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
502329SN/A        {
512292SN/A                Fault fault = NoFault;
529444SAndreas.Sandberg@ARM.com
538232Snate@binkert.org                %(fp_enable_check)s;
548232Snate@binkert.org
558232Snate@binkert.org                %(op_decl)s;
566221Snate@binkert.org                %(op_rd)s;
572292SN/A
586221Snate@binkert.org                if (%(predicate_test)s) {
595529Snate@binkert.org                    %(code)s;
602292SN/A                    if (fault == NoFault) {
615529Snate@binkert.org                        %(op_wb)s;
628707Sandreas.hansson@arm.com                    }
634329Sktlim@umich.edu                }
644329Sktlim@umich.edu
6510333Smitch.hayenga@arm.com                return fault;
662292SN/A        }
679868Sjthestness@gmail.com}};
689868Sjthestness@gmail.com
692292SN/Adef template FloatDoubleDecode {{
702292SN/A    {
712292SN/A        ArmStaticInst *i = NULL;
722980Sgblack@eecs.umich.edu        switch (OPCODE_19 << 1 | OPCODE_7)
732292SN/A        {
742292SN/A            case 0:
752292SN/A                i = (ArmStaticInst *)new %(class_name)sS(machInst);
762292SN/A                break;
772292SN/A            case 1:
782292SN/A                i = (ArmStaticInst *)new %(class_name)sD(machInst);
792292SN/A                break;
802292SN/A            case 2:
812292SN/A            case 3:
822292SN/A            default:
832292SN/A                panic("Cannot decode float/double nature of the instruction");
844329Sktlim@umich.edu        }
852292SN/A        return i;
862292SN/A    }
872292SN/A}};
882292SN/A
892292SN/A// Primary format for float point operate instructions:
902292SN/Adef format FloatOp(code, *flags) {{
912292SN/A        orig_code = code
924329Sktlim@umich.edu
932292SN/A        cblk = code
948346Sksewell@umich.edu        iop = InstObjParams(name, Name, 'PredOp',
952292SN/A                            {"code": cblk,
962292SN/A                             "predicate_test": predicateTest},
972292SN/A                            flags)
982292SN/A        header_output = BasicDeclare.subst(iop)
992292SN/A        decoder_output = BasicConstructor.subst(iop)
1002292SN/A        exec_output = FPAExecute.subst(iop)
1012292SN/A
1022292SN/A        sng_cblk = code
1032292SN/A        sng_iop = InstObjParams(name, Name+'S', 'PredOp',
1042292SN/A                                {"code": sng_cblk,
1052292SN/A                                 "predicate_test": predicateTest},
1062292SN/A                                flags)
1074329Sktlim@umich.edu        header_output += BasicDeclare.subst(sng_iop)
1082292SN/A        decoder_output += BasicConstructor.subst(sng_iop)
1098346Sksewell@umich.edu        exec_output += FPAExecute.subst(sng_iop)
1102292SN/A
1112292SN/A        dbl_code = re.sub(r'\.sf', '.df', orig_code)
1122292SN/A
1132292SN/A        dbl_cblk = dbl_code
1142292SN/A        dbl_iop = InstObjParams(name, Name+'D', 'PredOp',
1152292SN/A                                {"code": dbl_cblk,
1162292SN/A                                 "predicate_test": predicateTest},
1179868Sjthestness@gmail.com                                flags)
1186221Snate@binkert.org        header_output += BasicDeclare.subst(dbl_iop)
1194329Sktlim@umich.edu        decoder_output += BasicConstructor.subst(dbl_iop)
1204329Sktlim@umich.edu        exec_output += FPAExecute.subst(dbl_iop)
1218850Sandreas.hansson@arm.com
1222292SN/A        decode_block = FloatDoubleDecode.subst(iop)
1232292SN/A}};
1242292SN/A
1252292SN/Alet {{
1262292SN/A        calcFPCcCode = '''
1272292SN/A        uint16_t _in, _iz, _ic, _iv;
1282292SN/A
1292292SN/A        _in = %(fReg1)s < %(fReg2)s;
1302292SN/A        _iz = %(fReg1)s == %(fReg2)s;
1312292SN/A        _ic = %(fReg1)s >= %(fReg2)s;
1322292SN/A        _iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
1332292SN/A
1342292SN/A        CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
1352727Sktlim@umich.edu            (CondCodes & 0x0FFFFFFF);
1362727Sktlim@umich.edu        '''
1372727Sktlim@umich.edu}};
1386221Snate@binkert.org
1392727Sktlim@umich.edudef format FloatCmp(fReg1, fReg2, *flags) {{
1402727Sktlim@umich.edu        code = calcFPCcCode % vars()
1412727Sktlim@umich.edu        iop = InstObjParams(name, Name, 'PredOp',
1422727Sktlim@umich.edu                            {"code": code,
1432727Sktlim@umich.edu                             "predicate_test": predicateTest},
1442727Sktlim@umich.edu                             flags)
1456221Snate@binkert.org        header_output = BasicDeclare.subst(iop)
1462292SN/A        decoder_output = BasicConstructor.subst(iop)
1472292SN/A        decode_block = BasicDecode.subst(iop)
1482292SN/A        exec_output = FPAExecute.subst(iop)
1492292SN/A}};
1502292SN/A
1512292SN/Alet {{
1522307SN/A    header_output = '''
1539444SAndreas.Sandberg@ARM.com    StaticInstPtr
1542307SN/A    decodeExtensionRegLoadStore(ExtMachInst machInst);
1559444SAndreas.Sandberg@ARM.com    '''
1569444SAndreas.Sandberg@ARM.com    decoder_output = '''
1579444SAndreas.Sandberg@ARM.com    StaticInstPtr
1589444SAndreas.Sandberg@ARM.com    decodeExtensionRegLoadStore(ExtMachInst machInst)
1599444SAndreas.Sandberg@ARM.com    {
1609444SAndreas.Sandberg@ARM.com        const uint32_t opcode = bits(machInst, 24, 20);
1619444SAndreas.Sandberg@ARM.com        const uint32_t offset = bits(machInst, 7, 0);
1629444SAndreas.Sandberg@ARM.com        const bool single = (bits(machInst, 8) == 0);
1639444SAndreas.Sandberg@ARM.com        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1649444SAndreas.Sandberg@ARM.com        RegIndex vd;
1659444SAndreas.Sandberg@ARM.com        if (single) {
1669444SAndreas.Sandberg@ARM.com            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1679444SAndreas.Sandberg@ARM.com                                      bits(machInst, 22));
1689444SAndreas.Sandberg@ARM.com        } else {
1699444SAndreas.Sandberg@ARM.com            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1702307SN/A                                      (bits(machInst, 22) << 5));
1719444SAndreas.Sandberg@ARM.com        }
1729444SAndreas.Sandberg@ARM.com        switch (bits(opcode, 4, 3)) {
1739444SAndreas.Sandberg@ARM.com          case 0x0:
1749444SAndreas.Sandberg@ARM.com            if (bits(opcode, 4, 1) == 0x2 &&
1759444SAndreas.Sandberg@ARM.com                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
1769444SAndreas.Sandberg@ARM.com                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1779444SAndreas.Sandberg@ARM.com                if ((bits(machInst, 7, 4) & 0xd) != 1) {
1782307SN/A                    break;
1792307SN/A                }
1802307SN/A                const IntRegIndex rt =
1812307SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1822307SN/A                const IntRegIndex rt2 =
1832307SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1846221Snate@binkert.org                const bool op = bits(machInst, 20);
1852307SN/A                uint32_t vm;
1862307SN/A                if (single) {
1872307SN/A                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1882307SN/A                } else {
1892307SN/A                    vm = (bits(machInst, 3, 0) << 1) |
1902292SN/A                         (bits(machInst, 5) << 5);
1916221Snate@binkert.org                }
1922292SN/A                if (op) {
1932292SN/A                    return new Vmov2Core2Reg(machInst, rt, rt2,
1942292SN/A                                             (IntRegIndex)vm);
1952292SN/A                } else {
1962292SN/A                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1972292SN/A                                             rt, rt2);
1982292SN/A                }
1992292SN/A            }
2002292SN/A            break;
2012292SN/A          case 0x1:
2022292SN/A            switch (bits(opcode, 1, 0)) {
2032292SN/A              case 0x0:
2042292SN/A                return new VLdmStm(machInst, rn, vd, single,
2053867Sbinkertn@umich.edu                                   true, false, false, offset);
2062292SN/A              case 0x1:
2072292SN/A                return new VLdmStm(machInst, rn, vd, single,
2082292SN/A                                   true, false, true, offset);
2092292SN/A              case 0x2:
2102292SN/A                return new VLdmStm(machInst, rn, vd, single,
2112292SN/A                                   true, true, false, offset);
2122292SN/A              case 0x3:
2132292SN/A                // If rn == sp, then this is called vpop.
2142292SN/A                return new VLdmStm(machInst, rn, vd, single,
2152292SN/A                                   true, true, true, offset);
2162292SN/A            }
2176221Snate@binkert.org          case 0x2:
2186221Snate@binkert.org            if (bits(opcode, 1, 0) == 0x2) {
2193867Sbinkertn@umich.edu                // If rn == sp, then this is called vpush.
2203867Sbinkertn@umich.edu                return new VLdmStm(machInst, rn, vd, single,
2216221Snate@binkert.org                                   false, true, false, offset);
2223867Sbinkertn@umich.edu            } else if (bits(opcode, 1, 0) == 0x3) {
2233867Sbinkertn@umich.edu                return new VLdmStm(machInst, rn, vd, single,
2242292SN/A                                   false, true, true, offset);
2252292SN/A            }
2262292SN/A            // Fall through on purpose
2272292SN/A          case 0x3:
2282292SN/A            const bool up = (bits(machInst, 23) == 1);
2292292SN/A            const uint32_t imm = bits(machInst, 7, 0) << 2;
2306221Snate@binkert.org            RegIndex vd;
2312292SN/A            if (single) {
2322292SN/A                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
2332292SN/A                                          (bits(machInst, 22)));
2342292SN/A            } else {
2352292SN/A                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
2362292SN/A                                          (bits(machInst, 22) << 5));
2372292SN/A            }
2386221Snate@binkert.org            if (bits(opcode, 1, 0) == 0x0) {
2392292SN/A                if (single) {
2402292SN/A                    if (up) {
2412292SN/A                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
2422292SN/A                    } else {
2432292SN/A                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
2442292SN/A                    }
2452292SN/A                } else {
2462292SN/A                    if (up) {
2472292SN/A                        return new %(vstr_ud)s(machInst, vd, vd + 1,
2486221Snate@binkert.org                                               rn, up, imm);
2496221Snate@binkert.org                    } else {
2502292SN/A                        return new %(vstr_d)s(machInst, vd, vd + 1,
2513867Sbinkertn@umich.edu                                              rn, up, imm);
2526221Snate@binkert.org                    }
2532292SN/A                }
2542292SN/A            } else if (bits(opcode, 1, 0) == 0x1) {
2552292SN/A                if (single) {
2562292SN/A                    if (up) {
2572292SN/A                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
2582292SN/A                    } else {
2592292SN/A                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
2602292SN/A                    }
2612292SN/A                } else {
2626221Snate@binkert.org                    if (up) {
2632292SN/A                        return new %(vldr_ud)s(machInst, vd, vd + 1,
2642292SN/A                                               rn, up, imm);
2652292SN/A                    } else {
2662292SN/A                        return new %(vldr_d)s(machInst, vd, vd + 1,
2672292SN/A                                              rn, up, imm);
2682292SN/A                    }
2692292SN/A                }
2702292SN/A            }
2716221Snate@binkert.org        }
2722292SN/A        return new Unknown(machInst);
2732292SN/A    }
2742292SN/A    ''' % {
2752292SN/A        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
2762292SN/A        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
2772292SN/A        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
2782292SN/A        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
2792292SN/A        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
2806221Snate@binkert.org        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
2812292SN/A        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
2822292SN/A        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
2832292SN/A    }
2842292SN/A}};
2852292SN/A
2862292SN/Adef format ExtensionRegLoadStore() {{
2872292SN/A    decode_block = '''
2882292SN/A    return decodeExtensionRegLoadStore(machInst);
2896221Snate@binkert.org    '''
2902292SN/A}};
2912292SN/A
2922292SN/Alet {{
2932292SN/A    header_output = '''
2942292SN/A    StaticInstPtr
2952292SN/A    decodeShortFpTransfer(ExtMachInst machInst);
2962292SN/A    '''
2972292SN/A    decoder_output = '''
2986221Snate@binkert.org    StaticInstPtr
2996221Snate@binkert.org    decodeShortFpTransfer(ExtMachInst machInst)
3002292SN/A    {
3013867Sbinkertn@umich.edu        const uint32_t l = bits(machInst, 20);
3026221Snate@binkert.org        const uint32_t c = bits(machInst, 8);
3032292SN/A        const uint32_t a = bits(machInst, 23, 21);
3042292SN/A        const uint32_t b = bits(machInst, 6, 5);
3052329SN/A        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
3062329SN/A            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
3072292SN/A            return new Unknown(machInst);
3082292SN/A        }
3092292SN/A        if (l == 0 && c == 0) {
3102292SN/A            if (a == 0) {
3112292SN/A                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
3122292SN/A                                    bits(machInst, 7);
3132292SN/A                const IntRegIndex rt =
3142292SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3152292SN/A                if (bits(machInst, 20) == 1) {
3162292SN/A                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
3172292SN/A                } else {
3186221Snate@binkert.org                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
3196221Snate@binkert.org                }
3202292SN/A            } else if (a == 0x7) {
3213867Sbinkertn@umich.edu                const IntRegIndex rt =
3226221Snate@binkert.org                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3233867Sbinkertn@umich.edu                uint32_t specReg = bits(machInst, 19, 16);
3242292SN/A                switch (specReg) {
3252292SN/A                  case 0:
3262292SN/A                    specReg = MISCREG_FPSID;
3272292SN/A                    break;
3282292SN/A                  case 1:
3292292SN/A                    specReg = MISCREG_FPSCR;
3302292SN/A                    break;
3318707Sandreas.hansson@arm.com                  case 8:
3328707Sandreas.hansson@arm.com                    specReg = MISCREG_FPEXC;
3338707Sandreas.hansson@arm.com                    break;
3348707Sandreas.hansson@arm.com                  default:
33510333Smitch.hayenga@arm.com                    return new Unknown(machInst);
33610333Smitch.hayenga@arm.com                }
33710333Smitch.hayenga@arm.com                return new Vmsr(machInst, (IntRegIndex)specReg, rt);
33810333Smitch.hayenga@arm.com            }
3398707Sandreas.hansson@arm.com        } else if (l == 0 && c == 1) {
3408707Sandreas.hansson@arm.com            if (bits(a, 2) == 0) {
3418707Sandreas.hansson@arm.com                uint32_t vd = (bits(machInst, 7) << 5) |
3428707Sandreas.hansson@arm.com                              (bits(machInst, 19, 16) << 1);
3438707Sandreas.hansson@arm.com                uint32_t index, size;
3448975Sandreas.hansson@arm.com                const IntRegIndex rt =
3458707Sandreas.hansson@arm.com                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3468707Sandreas.hansson@arm.com                if (bits(machInst, 22) == 1) {
3478707Sandreas.hansson@arm.com                    size = 8;
3488707Sandreas.hansson@arm.com                    index = (bits(machInst, 21) << 2) |
34910575SMarco.Elver@ARM.com                            bits(machInst, 6, 5);
3508948Sandreas.hansson@arm.com                } else if (bits(machInst, 5) == 1) {
35110575SMarco.Elver@ARM.com                    size = 16;
35210575SMarco.Elver@ARM.com                    index = (bits(machInst, 21) << 1) |
35310575SMarco.Elver@ARM.com                            bits(machInst, 6);
35410575SMarco.Elver@ARM.com                } else if (bits(machInst, 6) == 0) {
35510575SMarco.Elver@ARM.com                    size = 32;
35610575SMarco.Elver@ARM.com                    index = bits(machInst, 21);
35710575SMarco.Elver@ARM.com                } else {
35810575SMarco.Elver@ARM.com                    return new Unknown(machInst);
35910575SMarco.Elver@ARM.com                }
36010575SMarco.Elver@ARM.com                if (index >= (32 / size)) {
36110575SMarco.Elver@ARM.com                    index -= (32 / size);
36210575SMarco.Elver@ARM.com                    vd++;
36310575SMarco.Elver@ARM.com                }
36410575SMarco.Elver@ARM.com                switch (size) {
36510575SMarco.Elver@ARM.com                  case 8:
36610575SMarco.Elver@ARM.com                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
36710575SMarco.Elver@ARM.com                                            rt, index);
36810575SMarco.Elver@ARM.com                  case 16:
36910575SMarco.Elver@ARM.com                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
37010575SMarco.Elver@ARM.com                                            rt, index);
37110575SMarco.Elver@ARM.com                  case 32:
37210573Sstephan.diestelhorst@arm.com                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
37310573Sstephan.diestelhorst@arm.com                }
3748948Sandreas.hansson@arm.com            } else if (bits(b, 1) == 0) {
3758948Sandreas.hansson@arm.com                // A8-594
3768707Sandreas.hansson@arm.com                return new WarnUnimplemented("vdup", machInst);
3778948Sandreas.hansson@arm.com            }
3788975Sandreas.hansson@arm.com        } else if (l == 1 && c == 0) {
3798975Sandreas.hansson@arm.com            if (a == 0) {
3808948Sandreas.hansson@arm.com                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
3818948Sandreas.hansson@arm.com                                    bits(machInst, 7);
3828948Sandreas.hansson@arm.com                const IntRegIndex rt =
3838948Sandreas.hansson@arm.com                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3848948Sandreas.hansson@arm.com                if (bits(machInst, 20) == 1) {
3858948Sandreas.hansson@arm.com                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
3868948Sandreas.hansson@arm.com                } else {
3878948Sandreas.hansson@arm.com                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
3888948Sandreas.hansson@arm.com                }
3898948Sandreas.hansson@arm.com            } else if (a == 7) {
3908707Sandreas.hansson@arm.com                const IntRegIndex rt =
3918707Sandreas.hansson@arm.com                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3928707Sandreas.hansson@arm.com                uint32_t specReg = bits(machInst, 19, 16);
3938707Sandreas.hansson@arm.com                switch (specReg) {
3942292SN/A                  case 0:
3952292SN/A                    specReg = MISCREG_FPSID;
3962292SN/A                    break;
3972292SN/A                  case 1:
3982292SN/A                    specReg = MISCREG_FPSCR;
3992292SN/A                    break;
4006221Snate@binkert.org                  case 6:
4016221Snate@binkert.org                    specReg = MISCREG_MVFR1;
4022292SN/A                    break;
4033867Sbinkertn@umich.edu                  case 7:
4046221Snate@binkert.org                    specReg = MISCREG_MVFR0;
4053867Sbinkertn@umich.edu                    break;
4062292SN/A                  case 8:
4072292SN/A                    specReg = MISCREG_FPEXC;
4082292SN/A                    break;
4092292SN/A                  default:
4102292SN/A                    return new Unknown(machInst);
4112292SN/A                }
4122292SN/A                return new Vmrs(machInst, rt, (IntRegIndex)specReg);
4132292SN/A            }
4142292SN/A        } else {
4152292SN/A            uint32_t vd = (bits(machInst, 7) << 5) |
4162292SN/A                          (bits(machInst, 19, 16) << 1);
4172292SN/A            uint32_t index, size;
4186221Snate@binkert.org            const IntRegIndex rt =
4196221Snate@binkert.org                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
4202292SN/A            const bool u = (bits(machInst, 23) == 1);
4213867Sbinkertn@umich.edu            if (bits(machInst, 22) == 1) {
4226221Snate@binkert.org                size = 8;
4233867Sbinkertn@umich.edu                index = (bits(machInst, 21) << 2) |
4242292SN/A                        bits(machInst, 6, 5);
4252292SN/A            } else if (bits(machInst, 5) == 1) {
4262292SN/A                size = 16;
4272292SN/A                index = (bits(machInst, 21) << 1) |
4282292SN/A                        bits(machInst, 6);
4292292SN/A            } else if (bits(machInst, 6) == 0 && !u) {
4302292SN/A                size = 32;
4312292SN/A                index = bits(machInst, 21);
4322292SN/A            } else {
4332292SN/A                return new Unknown(machInst);
4342292SN/A            }
4352292SN/A            if (index >= (32 / size)) {
4366221Snate@binkert.org                index -= (32 / size);
4376221Snate@binkert.org                vd++;
4382292SN/A            }
4393867Sbinkertn@umich.edu            switch (size) {
4406221Snate@binkert.org              case 8:
4413867Sbinkertn@umich.edu                if (u) {
4422292SN/A                    return new VmovRegCoreUB(machInst, rt,
4432292SN/A                                             (IntRegIndex)vd, index);
4442292SN/A                } else {
4452292SN/A                    return new VmovRegCoreSB(machInst, rt,
4462292SN/A                                             (IntRegIndex)vd, index);
4472292SN/A                }
4482292SN/A              case 16:
4492292SN/A                if (u) {
45010239Sbinhpham@cs.rutgers.edu                    return new VmovRegCoreUH(machInst, rt,
4512292SN/A                                             (IntRegIndex)vd, index);
4522292SN/A                } else {
4532292SN/A                    return new VmovRegCoreSH(machInst, rt,
4546221Snate@binkert.org                                             (IntRegIndex)vd, index);
4556221Snate@binkert.org                }
4562292SN/A              case 32:
4573867Sbinkertn@umich.edu                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
4586221Snate@binkert.org            }
4593867Sbinkertn@umich.edu        }
46010239Sbinhpham@cs.rutgers.edu        return new Unknown(machInst);
4612292SN/A    }
4622292SN/A    '''
4632292SN/A}};
4642292SN/A
4652292SN/Adef format ShortFpTransfer() {{
4662292SN/A    decode_block = '''
4672292SN/A    return decodeShortFpTransfer(machInst);
46810239Sbinhpham@cs.rutgers.edu    '''
4692292SN/A}};
47010239Sbinhpham@cs.rutgers.edu
47110239Sbinhpham@cs.rutgers.edulet {{
47210239Sbinhpham@cs.rutgers.edu    header_output = '''
47310239Sbinhpham@cs.rutgers.edu    StaticInstPtr
47410239Sbinhpham@cs.rutgers.edu    decodeVfpData(ExtMachInst machInst);
47510239Sbinhpham@cs.rutgers.edu    '''
47610239Sbinhpham@cs.rutgers.edu    decoder_output = '''
47710239Sbinhpham@cs.rutgers.edu    StaticInstPtr
47810239Sbinhpham@cs.rutgers.edu    decodeVfpData(ExtMachInst machInst)
47910239Sbinhpham@cs.rutgers.edu    {
48010239Sbinhpham@cs.rutgers.edu        const uint32_t opc1 = bits(machInst, 23, 20);
48110239Sbinhpham@cs.rutgers.edu        const uint32_t opc2 = bits(machInst, 19, 16);
48210239Sbinhpham@cs.rutgers.edu        const uint32_t opc3 = bits(machInst, 7, 6);
48310239Sbinhpham@cs.rutgers.edu        //const uint32_t opc4 = bits(machInst, 3, 0);
48410239Sbinhpham@cs.rutgers.edu        switch (opc1 & 0xb /* 1011 */) {
48510239Sbinhpham@cs.rutgers.edu          case 0x0:
48610239Sbinhpham@cs.rutgers.edu            return new WarnUnimplemented("vmla, vmls", machInst);
48710239Sbinhpham@cs.rutgers.edu          case 0x2:
48810239Sbinhpham@cs.rutgers.edu            if ((opc3 & 0x1) == 0) {
48910239Sbinhpham@cs.rutgers.edu                uint32_t vd;
49010239Sbinhpham@cs.rutgers.edu                uint32_t vm;
49110239Sbinhpham@cs.rutgers.edu                uint32_t vn;
49210239Sbinhpham@cs.rutgers.edu                if (bits(machInst, 8) == 0) {
49310239Sbinhpham@cs.rutgers.edu                    vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1);
49410239Sbinhpham@cs.rutgers.edu                    vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1);
49510239Sbinhpham@cs.rutgers.edu                    vn = bits(machInst, 7) | (bits(machInst, 19, 16) << 1);
4962292SN/A                    return new VmulS(machInst, (IntRegIndex)vd,
4972292SN/A                            (IntRegIndex)vn, (IntRegIndex)vm);
4982292SN/A                } else {
4992292SN/A                    vd = (bits(machInst, 22) << 5) |
5002292SN/A                         (bits(machInst, 15, 12) << 1);
5012292SN/A                    vm = (bits(machInst, 5) << 5) |
5026221Snate@binkert.org                         (bits(machInst, 3, 0) << 1);
5036221Snate@binkert.org                    vn = (bits(machInst, 7) << 5) |
5042292SN/A                         (bits(machInst, 19, 16) << 1);
5053867Sbinkertn@umich.edu                    return new VmulD(machInst, (IntRegIndex)vd,
5066221Snate@binkert.org                            (IntRegIndex)vn, (IntRegIndex)vm);
5073867Sbinkertn@umich.edu                }
5083867Sbinkertn@umich.edu            }
5092292SN/A          case 0x1:
5102292SN/A            return new WarnUnimplemented("vnmla, vnmls, vnmul", machInst);
5112292SN/A          case 0x3:
5122292SN/A            if ((opc3 & 0x1) == 0) {
5132292SN/A                uint32_t vd;
5142292SN/A                uint32_t vm;
5152292SN/A                uint32_t vn;
5162292SN/A                if (bits(machInst, 8) == 0) {
5176221Snate@binkert.org                    vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1);
5182292SN/A                    vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1);
5192292SN/A                    vn = bits(machInst, 7) | (bits(machInst, 19, 16) << 1);
5202292SN/A                    return new VaddS(machInst, (IntRegIndex)vd,
5213867Sbinkertn@umich.edu                            (IntRegIndex)vn, (IntRegIndex)vm);
5222292SN/A                } else {
5232292SN/A                    vd = (bits(machInst, 22) << 5) |
5242292SN/A                         (bits(machInst, 15, 12) << 1);
5252292SN/A                    vm = (bits(machInst, 5) << 5) |
5262292SN/A                         (bits(machInst, 3, 0) << 1);
5272292SN/A                    vn = (bits(machInst, 7) << 5) |
5282292SN/A                         (bits(machInst, 19, 16) << 1);
5299444SAndreas.Sandberg@ARM.com                    return new VaddD(machInst, (IntRegIndex)vd,
5309444SAndreas.Sandberg@ARM.com                            (IntRegIndex)vn, (IntRegIndex)vm);
5319444SAndreas.Sandberg@ARM.com                }
5329444SAndreas.Sandberg@ARM.com            } else {
5339444SAndreas.Sandberg@ARM.com                return new WarnUnimplemented("vsub", machInst);
5349444SAndreas.Sandberg@ARM.com            }
5359444SAndreas.Sandberg@ARM.com          case 0x8:
5369444SAndreas.Sandberg@ARM.com            if ((opc3 & 0x1) == 0) {
5379444SAndreas.Sandberg@ARM.com                return new WarnUnimplemented("vdiv", machInst);
5389444SAndreas.Sandberg@ARM.com            }
5399444SAndreas.Sandberg@ARM.com            break;
5409444SAndreas.Sandberg@ARM.com          case 0xb:
5419444SAndreas.Sandberg@ARM.com            if ((opc3 & 0x1) == 0) {
5429444SAndreas.Sandberg@ARM.com                uint32_t vd;
5439444SAndreas.Sandberg@ARM.com                const uint32_t baseImm =
5449444SAndreas.Sandberg@ARM.com                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
5459444SAndreas.Sandberg@ARM.com                if (bits(machInst, 8) == 0) {
5469444SAndreas.Sandberg@ARM.com                    vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1);
5479444SAndreas.Sandberg@ARM.com                    uint32_t imm = vfp_modified_imm(baseImm, false);
5489444SAndreas.Sandberg@ARM.com                    return new VmovImmS(machInst, (IntRegIndex)vd, imm);
5499444SAndreas.Sandberg@ARM.com                } else {
5509444SAndreas.Sandberg@ARM.com                    vd = (bits(machInst, 22) << 5) |
5519444SAndreas.Sandberg@ARM.com                         (bits(machInst, 15, 12) << 1);
5529444SAndreas.Sandberg@ARM.com                    uint64_t imm = vfp_modified_imm(baseImm, true);
5539444SAndreas.Sandberg@ARM.com                    return new VmovImmD(machInst, (IntRegIndex)vd, imm);
5549444SAndreas.Sandberg@ARM.com                }
5559444SAndreas.Sandberg@ARM.com            }
5569444SAndreas.Sandberg@ARM.com            switch (opc2) {
5579444SAndreas.Sandberg@ARM.com              case 0x0:
5589444SAndreas.Sandberg@ARM.com                if (opc3 == 1) {
5599444SAndreas.Sandberg@ARM.com                    uint32_t vd;
5609444SAndreas.Sandberg@ARM.com                    uint32_t vm;
5619444SAndreas.Sandberg@ARM.com                    if (bits(machInst, 8) == 0) {
5629444SAndreas.Sandberg@ARM.com                        vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1);
5639444SAndreas.Sandberg@ARM.com                        vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1);
5649444SAndreas.Sandberg@ARM.com                        return new VmovRegS(machInst,
5659444SAndreas.Sandberg@ARM.com                                (IntRegIndex)vd, (IntRegIndex)vm);
5669444SAndreas.Sandberg@ARM.com                    } else {
5679444SAndreas.Sandberg@ARM.com                        vd = (bits(machInst, 22) << 5) |
5689444SAndreas.Sandberg@ARM.com                             (bits(machInst, 15, 12) << 1);
5699444SAndreas.Sandberg@ARM.com                        vm = (bits(machInst, 5) << 5) |
5702292SN/A                             (bits(machInst, 3, 0) << 1);
5712292SN/A                        return new VmovRegD(machInst,
5726221Snate@binkert.org                                (IntRegIndex)vd, (IntRegIndex)vm);
5736221Snate@binkert.org                    }
5742292SN/A                } else {
5753867Sbinkertn@umich.edu                    uint32_t vd;
5766221Snate@binkert.org                    uint32_t vm;
5773867Sbinkertn@umich.edu                    if (bits(machInst, 8) == 0) {
5782292SN/A                        vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1);
5792292SN/A                        vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1);
5802292SN/A                        return new VabsS(machInst,
5812292SN/A                                (IntRegIndex)vd, (IntRegIndex)vm);
5822292SN/A                    } else {
5832292SN/A                        vd = (bits(machInst, 22) << 5) |
5842292SN/A                             (bits(machInst, 15, 12) << 1);
5852292SN/A                        vm = (bits(machInst, 5) << 5) |
5862292SN/A                             (bits(machInst, 3, 0) << 1);
5876221Snate@binkert.org                        return new VabsD(machInst,
5882292SN/A                                (IntRegIndex)vd, (IntRegIndex)vm);
5892292SN/A                    }
5902292SN/A                }
5913870Sbinkertn@umich.edu              case 0x1:
5922292SN/A                if (opc3 == 1) {
5932292SN/A                    uint32_t vd;
5942292SN/A                    uint32_t vm;
5952292SN/A                    if (bits(machInst, 8) == 0) {
5962292SN/A                        vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1);
5972292SN/A                        vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1);
5982292SN/A                        return new VnegS(machInst,
5992292SN/A                                (IntRegIndex)vd, (IntRegIndex)vm);
6002292SN/A                    } else {
6016221Snate@binkert.org                        vd = (bits(machInst, 22) << 5) |
6026221Snate@binkert.org                             (bits(machInst, 15, 12) << 1);
6032292SN/A                        vm = (bits(machInst, 5) << 5) |
6043867Sbinkertn@umich.edu                             (bits(machInst, 3, 0) << 1);
6056221Snate@binkert.org                        return new VnegD(machInst,
6063867Sbinkertn@umich.edu                                (IntRegIndex)vd, (IntRegIndex)vm);
6072292SN/A                    }
6082292SN/A                } else {
6092292SN/A                    return new WarnUnimplemented("vsqrt", machInst);
6102292SN/A                }
6112292SN/A              case 0x2:
6122292SN/A              case 0x3:
6132292SN/A                // Between half and single precision.
6142292SN/A                return new WarnUnimplemented("vcvtb, vcvtt", machInst);
6152292SN/A              case 0x4:
6166221Snate@binkert.org              case 0x5:
6172292SN/A                return new WarnUnimplemented("vcmp, vcmpe", machInst);
6182292SN/A              case 0x7:
6192292SN/A                if (opc3 == 0x3) {
6203870Sbinkertn@umich.edu                    // Between double and single precision.
6212292SN/A                    return new WarnUnimplemented("vcvt", machInst);
6222292SN/A                }
6232292SN/A                break;
6242292SN/A              case 0x8:
6252292SN/A                // Between FP and int.
6262292SN/A                return new WarnUnimplemented("vcvt, vcvtr", machInst);
6272292SN/A              case 0xa:
6282292SN/A              case 0xb:
6292292SN/A                // Between FP and fixed point.
6306221Snate@binkert.org                return new WarnUnimplemented("vcvt", machInst);
6316221Snate@binkert.org              case 0xc:
6322292SN/A              case 0xd:
6333867Sbinkertn@umich.edu                // Between FP and int.
6346221Snate@binkert.org                return new WarnUnimplemented("vcvt, vcvtr", machInst);
6353867Sbinkertn@umich.edu              case 0xe:
6362292SN/A              case 0xf:
6372292SN/A                // Between FP and fixed point.
6382292SN/A                return new WarnUnimplemented("vcvt", machInst);
6392292SN/A            }
6402292SN/A            break;
6412292SN/A        }
6422292SN/A        return new Unknown(machInst);
6432292SN/A    }
6442292SN/A    '''
6456221Snate@binkert.org}};
6462292SN/A
6473870Sbinkertn@umich.edudef format VfpData() {{
6482292SN/A    decode_block = '''
6492292SN/A    return decodeVfpData(machInst);
6502292SN/A    '''
6512292SN/A}};
6522292SN/A