fp.isa revision 7366
16657Snate@binkert.org// -*- mode:c++ -*-
26657Snate@binkert.org
36657Snate@binkert.org// Copyright (c) 2010 ARM Limited
46657Snate@binkert.org// All rights reserved
56657Snate@binkert.org//
66657Snate@binkert.org// The license below extends only to copyright in the software and shall
76657Snate@binkert.org// not be construed as granting a license to any other intellectual
86657Snate@binkert.org// property including but not limited to intellectual property relating
96657Snate@binkert.org// to a hardware implementation of the functionality of the software
106657Snate@binkert.org// licensed hereunder.  You may use the software subject to the license
116657Snate@binkert.org// terms below provided that you ensure that this notice is replicated
126657Snate@binkert.org// unmodified and in its entirety in all distributions of the software,
136657Snate@binkert.org// modified or unmodified, in source code or in binary form.
146657Snate@binkert.org//
156657Snate@binkert.org// Copyright (c) 2007-2008 The Florida State University
166657Snate@binkert.org// All rights reserved.
176657Snate@binkert.org//
186657Snate@binkert.org// Redistribution and use in source and binary forms, with or without
196657Snate@binkert.org// modification, are permitted provided that the following conditions are
206657Snate@binkert.org// met: redistributions of source code must retain the above copyright
216657Snate@binkert.org// notice, this list of conditions and the following disclaimer;
226657Snate@binkert.org// redistributions in binary form must reproduce the above copyright
236657Snate@binkert.org// notice, this list of conditions and the following disclaimer in the
246657Snate@binkert.org// documentation and/or other materials provided with the distribution;
256657Snate@binkert.org// neither the name of the copyright holders nor the names of its
266657Snate@binkert.org// contributors may be used to endorse or promote products derived from
276657Snate@binkert.org// this software without specific prior written permission.
2813672Sandreas.sandberg@arm.com//
296657Snate@binkert.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
306657Snate@binkert.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
316657Snate@binkert.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
329302Snilay@cs.wisc.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
336657Snate@binkert.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3411117Snilay@cs.wisc.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3511117Snilay@cs.wisc.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3611117Snilay@cs.wisc.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3711117Snilay@cs.wisc.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3811117Snilay@cs.wisc.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
396657Snate@binkert.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
406657Snate@binkert.org//
416657Snate@binkert.org// Authors: Stephen Hines
426657Snate@binkert.org
436657Snate@binkert.org////////////////////////////////////////////////////////////////////
446657Snate@binkert.org//
4511283Santhony.gutierrez@amd.com// Floating Point operate instructions
466657Snate@binkert.org//
476657Snate@binkert.org
486657Snate@binkert.orgdef template FPAExecute {{
496657Snate@binkert.org        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
506657Snate@binkert.org        {
516882SBrad.Beckmann@amd.com                Fault fault = NoFault;
526657Snate@binkert.org
536657Snate@binkert.org                %(fp_enable_check)s;
546657Snate@binkert.org
556657Snate@binkert.org                %(op_decl)s;
566657Snate@binkert.org                %(op_rd)s;
576657Snate@binkert.org
586657Snate@binkert.org                if (%(predicate_test)s) {
596657Snate@binkert.org                    %(code)s;
606657Snate@binkert.org                    if (fault == NoFault) {
616657Snate@binkert.org                        %(op_wb)s;
626657Snate@binkert.org                    }
636657Snate@binkert.org                }
646657Snate@binkert.org
6510895Snilay@cs.wisc.edu                return fault;
666657Snate@binkert.org        }
676657Snate@binkert.org}};
686657Snate@binkert.org
6910228Snilay@cs.wisc.edudef template FloatDoubleDecode {{
706657Snate@binkert.org    {
716657Snate@binkert.org        ArmStaticInst *i = NULL;
7210228Snilay@cs.wisc.edu        switch (OPCODE_19 << 1 | OPCODE_7)
736657Snate@binkert.org        {
746657Snate@binkert.org            case 0:
756657Snate@binkert.org                i = (ArmStaticInst *)new %(class_name)sS(machInst);
766657Snate@binkert.org                break;
776657Snate@binkert.org            case 1:
786657Snate@binkert.org                i = (ArmStaticInst *)new %(class_name)sD(machInst);
796657Snate@binkert.org                break;
806657Snate@binkert.org            case 2:
816657Snate@binkert.org            case 3:
826657Snate@binkert.org            default:
836657Snate@binkert.org                panic("Cannot decode float/double nature of the instruction");
846657Snate@binkert.org        }
856657Snate@binkert.org        return i;
866657Snate@binkert.org    }
876657Snate@binkert.org}};
886657Snate@binkert.org
898086SBrad.Beckmann@amd.com// Primary format for float point operate instructions:
908086SBrad.Beckmann@amd.comdef format FloatOp(code, *flags) {{
918086SBrad.Beckmann@amd.com        orig_code = code
9213672Sandreas.sandberg@arm.com
936657Snate@binkert.org        cblk = code
9413672Sandreas.sandberg@arm.com        iop = InstObjParams(name, Name, 'PredOp',
956657Snate@binkert.org                            {"code": cblk,
966657Snate@binkert.org                             "predicate_test": predicateTest},
976657Snate@binkert.org                            flags)
986657Snate@binkert.org        header_output = BasicDeclare.subst(iop)
9910895Snilay@cs.wisc.edu        decoder_output = BasicConstructor.subst(iop)
1006657Snate@binkert.org        exec_output = FPAExecute.subst(iop)
1016657Snate@binkert.org
1026657Snate@binkert.org        sng_cblk = code
1036657Snate@binkert.org        sng_iop = InstObjParams(name, Name+'S', 'PredOp',
1046657Snate@binkert.org                                {"code": sng_cblk,
1056657Snate@binkert.org                                 "predicate_test": predicateTest},
1066657Snate@binkert.org                                flags)
1076657Snate@binkert.org        header_output += BasicDeclare.subst(sng_iop)
1086657Snate@binkert.org        decoder_output += BasicConstructor.subst(sng_iop)
1096657Snate@binkert.org        exec_output += FPAExecute.subst(sng_iop)
1106657Snate@binkert.org
1116657Snate@binkert.org        dbl_code = re.sub(r'\.sf', '.df', orig_code)
1126657Snate@binkert.org
1136657Snate@binkert.org        dbl_cblk = dbl_code
1146657Snate@binkert.org        dbl_iop = InstObjParams(name, Name+'D', 'PredOp',
1156657Snate@binkert.org                                {"code": dbl_cblk,
1166657Snate@binkert.org                                 "predicate_test": predicateTest},
1176657Snate@binkert.org                                flags)
1186657Snate@binkert.org        header_output += BasicDeclare.subst(dbl_iop)
1196657Snate@binkert.org        decoder_output += BasicConstructor.subst(dbl_iop)
1206657Snate@binkert.org        exec_output += FPAExecute.subst(dbl_iop)
1216657Snate@binkert.org
1226657Snate@binkert.org        decode_block = FloatDoubleDecode.subst(iop)
1236657Snate@binkert.org}};
1246657Snate@binkert.org
1256657Snate@binkert.orglet {{
1269298Snilay@cs.wisc.edu        calcFPCcCode = '''
1276657Snate@binkert.org        uint16_t _in, _iz, _ic, _iv;
1286657Snate@binkert.org
1296657Snate@binkert.org        _in = %(fReg1)s < %(fReg2)s;
13011117Snilay@cs.wisc.edu        _iz = %(fReg1)s == %(fReg2)s;
13111117Snilay@cs.wisc.edu        _ic = %(fReg1)s >= %(fReg2)s;
13211117Snilay@cs.wisc.edu        _iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
1336657Snate@binkert.org
13411117Snilay@cs.wisc.edu        CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
1356657Snate@binkert.org            (CondCodes & 0x0FFFFFFF);
1366657Snate@binkert.org        '''
1376657Snate@binkert.org}};
1386657Snate@binkert.org
1396657Snate@binkert.orgdef format FloatCmp(fReg1, fReg2, *flags) {{
1406657Snate@binkert.org        code = calcFPCcCode % vars()
1416657Snate@binkert.org        iop = InstObjParams(name, Name, 'PredOp',
1426657Snate@binkert.org                            {"code": code,
1436882SBrad.Beckmann@amd.com                             "predicate_test": predicateTest},
1446882SBrad.Beckmann@amd.com                             flags)
1456882SBrad.Beckmann@amd.com        header_output = BasicDeclare.subst(iop)
1468086SBrad.Beckmann@amd.com        decoder_output = BasicConstructor.subst(iop)
1478086SBrad.Beckmann@amd.com        decode_block = BasicDecode.subst(iop)
1488086SBrad.Beckmann@amd.com        exec_output = FPAExecute.subst(iop)
14910307Snilay@cs.wisc.edu}};
15010307Snilay@cs.wisc.edu
1516657Snate@binkert.orglet {{
1526657Snate@binkert.org    header_output = '''
1536657Snate@binkert.org    StaticInstPtr
15410307Snilay@cs.wisc.edu    decodeExtensionRegLoadStore(ExtMachInst machInst);
1559298Snilay@cs.wisc.edu    '''
1569298Snilay@cs.wisc.edu    decoder_output = '''
1579298Snilay@cs.wisc.edu    StaticInstPtr
1586657Snate@binkert.org    decodeExtensionRegLoadStore(ExtMachInst machInst)
1596657Snate@binkert.org    {
1606657Snate@binkert.org        const uint32_t opcode = bits(machInst, 24, 20);
1616657Snate@binkert.org        const uint32_t offset = bits(machInst, 7, 0);
1626657Snate@binkert.org        const bool single = (bits(machInst, 8) == 0);
1636657Snate@binkert.org        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1646657Snate@binkert.org        RegIndex vd;
1656657Snate@binkert.org        if (single) {
1666657Snate@binkert.org            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
1676657Snate@binkert.org                                      bits(machInst, 22));
1686657Snate@binkert.org        } else {
16911283Santhony.gutierrez@amd.com            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
17011283Santhony.gutierrez@amd.com                                      (bits(machInst, 22) << 5));
17111283Santhony.gutierrez@amd.com        }
17211283Santhony.gutierrez@amd.com        switch (bits(opcode, 4, 3)) {
17311283Santhony.gutierrez@amd.com          case 0x0:
17411283Santhony.gutierrez@amd.com            if (bits(opcode, 4, 1) == 0x2 &&
17511283Santhony.gutierrez@amd.com                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
17611283Santhony.gutierrez@amd.com                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
1779219Spower.jg@gmail.com                if ((bits(machInst, 7, 4) & 0xd) != 1) {
1786657Snate@binkert.org                    break;
1796657Snate@binkert.org                }
1806657Snate@binkert.org                const IntRegIndex rt =
1816657Snate@binkert.org                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1826657Snate@binkert.org                const IntRegIndex rt2 =
1836657Snate@binkert.org                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1846657Snate@binkert.org                const bool op = bits(machInst, 20);
1856657Snate@binkert.org                uint32_t vm;
1866657Snate@binkert.org                if (single) {
1876657Snate@binkert.org                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
1886657Snate@binkert.org                } else {
1896657Snate@binkert.org                    vm = (bits(machInst, 3, 0) << 1) |
1906999Snate@binkert.org                         (bits(machInst, 5) << 5);
1916657Snate@binkert.org                }
1926657Snate@binkert.org                if (op) {
1936657Snate@binkert.org                    return new Vmov2Core2Reg(machInst, rt, rt2,
1946657Snate@binkert.org                                             (IntRegIndex)vm);
1956657Snate@binkert.org                } else {
1966657Snate@binkert.org                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1976657Snate@binkert.org                                             rt, rt2);
1987007Snate@binkert.org                }
1997007Snate@binkert.org            }
2006657Snate@binkert.org            break;
2017002Snate@binkert.org          case 0x1:
2027002Snate@binkert.org            switch (bits(opcode, 1, 0)) {
2039466Snilay@cs.wisc.edu              case 0x0:
2046657Snate@binkert.org                return new VLdmStm(machInst, rn, vd, single,
2056657Snate@binkert.org                                   true, false, false, offset);
2066657Snate@binkert.org              case 0x1:
2076657Snate@binkert.org                return new VLdmStm(machInst, rn, vd, single,
2086657Snate@binkert.org                                   true, false, true, offset);
2096657Snate@binkert.org              case 0x2:
2106657Snate@binkert.org                return new VLdmStm(machInst, rn, vd, single,
2116657Snate@binkert.org                                   true, true, false, offset);
2126657Snate@binkert.org              case 0x3:
2136657Snate@binkert.org                // If rn == sp, then this is called vpop.
2146657Snate@binkert.org                return new VLdmStm(machInst, rn, vd, single,
2156657Snate@binkert.org                                   true, true, true, offset);
2167007Snate@binkert.org            }
2177007Snate@binkert.org          case 0x2:
2186657Snate@binkert.org            if (bits(opcode, 1, 0) == 0x2) {
2199466Snilay@cs.wisc.edu                // If rn == sp, then this is called vpush.
2206657Snate@binkert.org                return new VLdmStm(machInst, rn, vd, single,
2216657Snate@binkert.org                                   false, true, false, offset);
2229466Snilay@cs.wisc.edu            } else if (bits(opcode, 1, 0) == 0x3) {
2239508Snilay@cs.wisc.edu                return new VLdmStm(machInst, rn, vd, single,
2249466Snilay@cs.wisc.edu                                   false, true, true, offset);
2259466Snilay@cs.wisc.edu            }
2269466Snilay@cs.wisc.edu            // Fall through on purpose
2276657Snate@binkert.org          case 0x3:
2286657Snate@binkert.org            const bool up = (bits(machInst, 23) == 1);
2296657Snate@binkert.org            const uint32_t imm = bits(machInst, 7, 0) << 2;
2306657Snate@binkert.org            RegIndex vd;
2316657Snate@binkert.org            if (single) {
2326657Snate@binkert.org                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
2336657Snate@binkert.org                                          (bits(machInst, 22)));
2346657Snate@binkert.org            } else {
2356657Snate@binkert.org                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
2366657Snate@binkert.org                                          (bits(machInst, 22) << 5));
2376657Snate@binkert.org            }
2386657Snate@binkert.org            if (bits(opcode, 1, 0) == 0x0) {
2396657Snate@binkert.org                if (single) {
2406657Snate@binkert.org                    if (up) {
2416657Snate@binkert.org                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
2426657Snate@binkert.org                    } else {
2436657Snate@binkert.org                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
2447453Snate@binkert.org                    }
2457453Snate@binkert.org                } else {
2467453Snate@binkert.org                    if (up) {
2477453Snate@binkert.org                        return new %(vstr_ud)s(machInst, vd, vd + 1,
2487453Snate@binkert.org                                               rn, up, imm);
2497453Snate@binkert.org                    } else {
2507453Snate@binkert.org                        return new %(vstr_d)s(machInst, vd, vd + 1,
2517453Snate@binkert.org                                              rn, up, imm);
2527453Snate@binkert.org                    }
2537453Snate@binkert.org                }
2547453Snate@binkert.org            } else if (bits(opcode, 1, 0) == 0x1) {
2557453Snate@binkert.org                if (single) {
2567453Snate@binkert.org                    if (up) {
2577453Snate@binkert.org                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
2587453Snate@binkert.org                    } else {
2597453Snate@binkert.org                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
2607453Snate@binkert.org                    }
2616657Snate@binkert.org                } else {
2626657Snate@binkert.org                    if (up) {
2636657Snate@binkert.org                        return new %(vldr_ud)s(machInst, vd, vd + 1,
2646657Snate@binkert.org                                               rn, up, imm);
2659466Snilay@cs.wisc.edu                    } else {
2666657Snate@binkert.org                        return new %(vldr_d)s(machInst, vd, vd + 1,
2679466Snilay@cs.wisc.edu                                              rn, up, imm);
2689508Snilay@cs.wisc.edu                    }
2699466Snilay@cs.wisc.edu                }
2706657Snate@binkert.org            }
2716657Snate@binkert.org        }
2726657Snate@binkert.org        return new Unknown(machInst);
2736657Snate@binkert.org    }
2749466Snilay@cs.wisc.edu    ''' % {
2759466Snilay@cs.wisc.edu        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
2769466Snilay@cs.wisc.edu        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
2779466Snilay@cs.wisc.edu        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
2786657Snate@binkert.org        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
2796657Snate@binkert.org        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
2806657Snate@binkert.org        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
2816657Snate@binkert.org        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
2826657Snate@binkert.org        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
2836657Snate@binkert.org    }
2846657Snate@binkert.org}};
2856657Snate@binkert.org
2866657Snate@binkert.orgdef format ExtensionRegLoadStore() {{
2879466Snilay@cs.wisc.edu    decode_block = '''
28810472Sandreas.hansson@arm.com    return decodeExtensionRegLoadStore(machInst);
28910472Sandreas.hansson@arm.com    '''
29010472Sandreas.hansson@arm.com}};
29110472Sandreas.hansson@arm.com
29210472Sandreas.hansson@arm.comlet {{
29310472Sandreas.hansson@arm.com    header_output = '''
29410472Sandreas.hansson@arm.com    StaticInstPtr
29510472Sandreas.hansson@arm.com    decodeShortFpTransfer(ExtMachInst machInst);
29610472Sandreas.hansson@arm.com    '''
29710472Sandreas.hansson@arm.com    decoder_output = '''
2987453Snate@binkert.org    StaticInstPtr
2997007Snate@binkert.org    decodeShortFpTransfer(ExtMachInst machInst)
3007007Snate@binkert.org    {
3017453Snate@binkert.org        const uint32_t l = bits(machInst, 20);
3027007Snate@binkert.org        const uint32_t c = bits(machInst, 8);
3036657Snate@binkert.org        const uint32_t a = bits(machInst, 23, 21);
3046657Snate@binkert.org        const uint32_t b = bits(machInst, 6, 5);
3056657Snate@binkert.org        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
3066657Snate@binkert.org            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
3076657Snate@binkert.org            return new Unknown(machInst);
3086657Snate@binkert.org        }
3096657Snate@binkert.org        if (l == 0 && c == 0) {
3106657Snate@binkert.org            if (a == 0) {
3116657Snate@binkert.org                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
3126657Snate@binkert.org                                    bits(machInst, 7);
3137007Snate@binkert.org                const IntRegIndex rt =
3147007Snate@binkert.org                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3157007Snate@binkert.org                if (bits(machInst, 20) == 1) {
3167007Snate@binkert.org                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
3177007Snate@binkert.org                } else {
3186657Snate@binkert.org                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
3196657Snate@binkert.org                }
3206657Snate@binkert.org            } else if (a == 0x7) {
3216657Snate@binkert.org                const IntRegIndex rt =
3226657Snate@binkert.org                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3236657Snate@binkert.org                uint32_t specReg = bits(machInst, 19, 16);
3246657Snate@binkert.org                switch (specReg) {
3256657Snate@binkert.org                  case 0:
3266657Snate@binkert.org                    specReg = MISCREG_FPSID;
3277007Snate@binkert.org                    break;
3287007Snate@binkert.org                  case 1:
3297007Snate@binkert.org                    specReg = MISCREG_FPSCR;
3307007Snate@binkert.org                    break;
3317007Snate@binkert.org                  case 8:
3326657Snate@binkert.org                    specReg = MISCREG_FPEXC;
3336657Snate@binkert.org                    break;
3346657Snate@binkert.org                  default:
3356657Snate@binkert.org                    return new Unknown(machInst);
3366657Snate@binkert.org                }
3376657Snate@binkert.org                return new Vmsr(machInst, (IntRegIndex)specReg, rt);
3386657Snate@binkert.org            }
3397007Snate@binkert.org        } else if (l == 0 && c == 1) {
3407007Snate@binkert.org            if (bits(a, 2) == 0) {
3417007Snate@binkert.org                uint32_t vd = (bits(machInst, 7) << 5) |
3427007Snate@binkert.org                              (bits(machInst, 19, 16) << 1);
3437007Snate@binkert.org                uint32_t index, size;
3446657Snate@binkert.org                const IntRegIndex rt =
3456657Snate@binkert.org                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3467002Snate@binkert.org                if (bits(machInst, 22) == 1) {
3476657Snate@binkert.org                    size = 8;
3486657Snate@binkert.org                    index = (bits(machInst, 21) << 2) |
3496657Snate@binkert.org                            bits(machInst, 6, 5);
3506657Snate@binkert.org                } else if (bits(machInst, 5) == 1) {
3516657Snate@binkert.org                    size = 16;
3526657Snate@binkert.org                    index = (bits(machInst, 21) << 1) |
3536657Snate@binkert.org                            bits(machInst, 6);
3546657Snate@binkert.org                } else if (bits(machInst, 6) == 0) {
3556657Snate@binkert.org                    size = 32;
3566657Snate@binkert.org                    index = bits(machInst, 21);
3576657Snate@binkert.org                } else {
3586657Snate@binkert.org                    return new Unknown(machInst);
3596657Snate@binkert.org                }
3606657Snate@binkert.org                if (index >= (32 / size)) {
3616657Snate@binkert.org                    index -= (32 / size);
3626657Snate@binkert.org                    vd++;
3636657Snate@binkert.org                }
3646657Snate@binkert.org                switch (size) {
3656657Snate@binkert.org                  case 8:
3666657Snate@binkert.org                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
3676657Snate@binkert.org                                            rt, index);
3687007Snate@binkert.org                  case 16:
3696657Snate@binkert.org                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
3707007Snate@binkert.org                                            rt, index);
3716657Snate@binkert.org                  case 32:
37210307Snilay@cs.wisc.edu                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
37310307Snilay@cs.wisc.edu                }
37410307Snilay@cs.wisc.edu            } else if (bits(b, 1) == 0) {
3759298Snilay@cs.wisc.edu                // A8-594
3769298Snilay@cs.wisc.edu                return new WarnUnimplemented("vdup", machInst);
3779298Snilay@cs.wisc.edu            }
3786657Snate@binkert.org        } else if (l == 1 && c == 0) {
3796657Snate@binkert.org            if (a == 0) {
3806657Snate@binkert.org                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
3816657Snate@binkert.org                                    bits(machInst, 7);
3827055Snate@binkert.org                const IntRegIndex rt =
3837007Snate@binkert.org                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3846657Snate@binkert.org                if (bits(machInst, 20) == 1) {
3856657Snate@binkert.org                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
3867002Snate@binkert.org                } else {
3876657Snate@binkert.org                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
3886657Snate@binkert.org                }
3896657Snate@binkert.org            } else if (a == 7) {
3907007Snate@binkert.org                const IntRegIndex rt =
3916657Snate@binkert.org                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3926657Snate@binkert.org                uint32_t specReg = bits(machInst, 19, 16);
3936657Snate@binkert.org                switch (specReg) {
3946657Snate@binkert.org                  case 0:
3956657Snate@binkert.org                    specReg = MISCREG_FPSID;
3966999Snate@binkert.org                    break;
3976657Snate@binkert.org                  case 1:
3986657Snate@binkert.org                    specReg = MISCREG_FPSCR;
3996657Snate@binkert.org                    break;
4006657Snate@binkert.org                  case 6:
4016657Snate@binkert.org                    specReg = MISCREG_MVFR1;
4026657Snate@binkert.org                    break;
4036657Snate@binkert.org                  case 7:
4047002Snate@binkert.org                    specReg = MISCREG_MVFR0;
40510472Sandreas.hansson@arm.com                    break;
4067002Snate@binkert.org                  case 8:
4076657Snate@binkert.org                    specReg = MISCREG_FPEXC;
40811108Sdavid.hashe@amd.com                    break;
4097002Snate@binkert.org                  default:
4107002Snate@binkert.org                    return new Unknown(machInst);
4116657Snate@binkert.org                }
4126657Snate@binkert.org                return new Vmrs(machInst, rt, (IntRegIndex)specReg);
4136657Snate@binkert.org            }
4146657Snate@binkert.org        } else {
4157007Snate@binkert.org            uint32_t vd = (bits(machInst, 7) << 5) |
4167007Snate@binkert.org                          (bits(machInst, 19, 16) << 1);
4176657Snate@binkert.org            uint32_t index, size;
4186657Snate@binkert.org            const IntRegIndex rt =
4196657Snate@binkert.org                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
4206657Snate@binkert.org            const bool u = (bits(machInst, 23) == 1);
4216657Snate@binkert.org            if (bits(machInst, 22) == 1) {
4226657Snate@binkert.org                size = 8;
4236657Snate@binkert.org                index = (bits(machInst, 21) << 2) |
42411118Snilay@cs.wisc.edu                        bits(machInst, 6, 5);
42511118Snilay@cs.wisc.edu            } else if (bits(machInst, 5) == 1) {
42611118Snilay@cs.wisc.edu                size = 16;
42711118Snilay@cs.wisc.edu                index = (bits(machInst, 21) << 1) |
42811118Snilay@cs.wisc.edu                        bits(machInst, 6);
4296657Snate@binkert.org            } else if (bits(machInst, 6) == 0 && !u) {
4306657Snate@binkert.org                size = 32;
4316657Snate@binkert.org                index = bits(machInst, 21);
4326657Snate@binkert.org            } else {
4336657Snate@binkert.org                return new Unknown(machInst);
4346657Snate@binkert.org            }
4356657Snate@binkert.org            if (index >= (32 / size)) {
4366657Snate@binkert.org                index -= (32 / size);
43710307Snilay@cs.wisc.edu                vd++;
43810307Snilay@cs.wisc.edu            }
43910307Snilay@cs.wisc.edu            switch (size) {
4409298Snilay@cs.wisc.edu              case 8:
4416657Snate@binkert.org                if (u) {
4426657Snate@binkert.org                    return new VmovRegCoreUB(machInst, rt,
4436657Snate@binkert.org                                             (IntRegIndex)vd, index);
4446999Snate@binkert.org                } else {
4456657Snate@binkert.org                    return new VmovRegCoreSB(machInst, rt,
4466657Snate@binkert.org                                             (IntRegIndex)vd, index);
4476657Snate@binkert.org                }
4486657Snate@binkert.org              case 16:
4496657Snate@binkert.org                if (u) {
4507007Snate@binkert.org                    return new VmovRegCoreUH(machInst, rt,
4517007Snate@binkert.org                                             (IntRegIndex)vd, index);
4527007Snate@binkert.org                } else {
4536657Snate@binkert.org                    return new VmovRegCoreSH(machInst, rt,
4547002Snate@binkert.org                                             (IntRegIndex)vd, index);
4557002Snate@binkert.org                }
4567002Snate@binkert.org              case 32:
4578086SBrad.Beckmann@amd.com                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
4588086SBrad.Beckmann@amd.com            }
4598086SBrad.Beckmann@amd.com        }
4608086SBrad.Beckmann@amd.com        return new Unknown(machInst);
4618602Snilay@cs.wisc.edu    }
46212065Snikos.nikoleris@arm.com    '''
46312334Sgabeblack@google.com}};
4648602Snilay@cs.wisc.edu
46511025Snilay@cs.wisc.edudef format ShortFpTransfer() {{
4668602Snilay@cs.wisc.edu    decode_block = '''
4678602Snilay@cs.wisc.edu    return decodeShortFpTransfer(machInst);
4688086SBrad.Beckmann@amd.com    '''
4696657Snate@binkert.org}};
4707007Snate@binkert.org
4716657Snate@binkert.orglet {{
4726657Snate@binkert.org    header_output = '''
4736657Snate@binkert.org    StaticInstPtr
4746657Snate@binkert.org    decodeVfpData(ExtMachInst machInst);
4756657Snate@binkert.org    '''
4766657Snate@binkert.org    decoder_output = '''
4776657Snate@binkert.org    StaticInstPtr
4786657Snate@binkert.org    decodeVfpData(ExtMachInst machInst)
4796657Snate@binkert.org    {
4806657Snate@binkert.org        const uint32_t opc1 = bits(machInst, 23, 20);
4816657Snate@binkert.org        const uint32_t opc2 = bits(machInst, 19, 16);
48210917Sbrandon.potter@amd.com        const uint32_t opc3 = bits(machInst, 7, 6);
48310917Sbrandon.potter@amd.com        //const uint32_t opc4 = bits(machInst, 3, 0);
4846862Sdrh5@cs.wisc.edu        switch (opc1 & 0xb /* 1011 */) {
4856862Sdrh5@cs.wisc.edu          case 0x0:
4866657Snate@binkert.org            return new WarnUnimplemented("vmla, vmls", machInst);
4876657Snate@binkert.org          case 0x2:
4886657Snate@binkert.org            if ((opc3 & 0x1) == 0) {
4896657Snate@binkert.org                uint32_t vd;
4906657Snate@binkert.org                uint32_t vm;
4917007Snate@binkert.org                uint32_t vn;
4927007Snate@binkert.org                if (bits(machInst, 8) == 0) {
4937002Snate@binkert.org                    vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1);
4947007Snate@binkert.org                    vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1);
4957007Snate@binkert.org                    vn = bits(machInst, 7) | (bits(machInst, 19, 16) << 1);
4967002Snate@binkert.org                    return new VmulS(machInst, (IntRegIndex)vd,
4977007Snate@binkert.org                            (IntRegIndex)vn, (IntRegIndex)vm);
4987007Snate@binkert.org                } else {
4996657Snate@binkert.org                    vd = (bits(machInst, 22) << 5) |
5006657Snate@binkert.org                         (bits(machInst, 15, 12) << 1);
5016657Snate@binkert.org                    vm = (bits(machInst, 5) << 5) |
50212065Snikos.nikoleris@arm.com                         (bits(machInst, 3, 0) << 1);
50312065Snikos.nikoleris@arm.com                    vn = (bits(machInst, 7) << 5) |
50412065Snikos.nikoleris@arm.com                         (bits(machInst, 19, 16) << 1);
50512065Snikos.nikoleris@arm.com                    return new VmulD(machInst, (IntRegIndex)vd,
50612065Snikos.nikoleris@arm.com                            (IntRegIndex)vn, (IntRegIndex)vm);
50712065Snikos.nikoleris@arm.com                }
50812065Snikos.nikoleris@arm.com            }
50912065Snikos.nikoleris@arm.com          case 0x1:
51012065Snikos.nikoleris@arm.com            return new WarnUnimplemented("vnmla, vnmls, vnmul", machInst);
51112065Snikos.nikoleris@arm.com          case 0x3:
51212065Snikos.nikoleris@arm.com            if ((opc3 & 0x1) == 0) {
51312065Snikos.nikoleris@arm.com                return new WarnUnimplemented("vadd", machInst);
51412065Snikos.nikoleris@arm.com            } else {
51512065Snikos.nikoleris@arm.com                return new WarnUnimplemented("vsub", machInst);
5166657Snate@binkert.org            }
5176657Snate@binkert.org          case 0x8:
5186657Snate@binkert.org            if ((opc3 & 0x1) == 0) {
5196657Snate@binkert.org                return new WarnUnimplemented("vdiv", machInst);
5206657Snate@binkert.org            }
5216657Snate@binkert.org            break;
5226657Snate@binkert.org          case 0xb:
5236657Snate@binkert.org            if ((opc3 & 0x1) == 0) {
5246657Snate@binkert.org                uint32_t vd;
5256657Snate@binkert.org                const uint32_t baseImm =
5268602Snilay@cs.wisc.edu                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
5278602Snilay@cs.wisc.edu                if (bits(machInst, 8) == 0) {
5288602Snilay@cs.wisc.edu                    vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1);
5298602Snilay@cs.wisc.edu                    uint32_t imm = vfp_modified_imm(baseImm, false);
5308602Snilay@cs.wisc.edu                    return new VmovImmS(machInst, (IntRegIndex)vd, imm);
5318086SBrad.Beckmann@amd.com                } else {
5328086SBrad.Beckmann@amd.com                    vd = (bits(machInst, 22) << 5) |
5338086SBrad.Beckmann@amd.com                         (bits(machInst, 15, 12) << 1);
5348086SBrad.Beckmann@amd.com                    uint64_t imm = vfp_modified_imm(baseImm, true);
5358086SBrad.Beckmann@amd.com                    return new VmovImmD(machInst, (IntRegIndex)vd, imm);
5368086SBrad.Beckmann@amd.com                }
5378086SBrad.Beckmann@amd.com            }
5388086SBrad.Beckmann@amd.com            switch (opc2) {
5396657Snate@binkert.org              case 0x0:
5406657Snate@binkert.org                if (opc3 == 1) {
5417002Snate@binkert.org                    uint32_t vd;
5426657Snate@binkert.org                    uint32_t vm;
5437007Snate@binkert.org                    if (bits(machInst, 8) == 0) {
5446657Snate@binkert.org                        vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1);
5456657Snate@binkert.org                        vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1);
5466657Snate@binkert.org                        return new VmovRegS(machInst,
5476657Snate@binkert.org                                (IntRegIndex)vd, (IntRegIndex)vm);
5486657Snate@binkert.org                    } else {
5496999Snate@binkert.org                        vd = (bits(machInst, 22) << 5) |
5506657Snate@binkert.org                             (bits(machInst, 15, 12) << 1);
5516657Snate@binkert.org                        vm = (bits(machInst, 5) << 5) |
5526657Snate@binkert.org                             (bits(machInst, 3, 0) << 1);
5536657Snate@binkert.org                        return new VmovRegD(machInst,
5546657Snate@binkert.org                                (IntRegIndex)vd, (IntRegIndex)vm);
5556657Snate@binkert.org                    }
5567832Snate@binkert.org                } else {
5577002Snate@binkert.org                    uint32_t vd;
5587002Snate@binkert.org                    uint32_t vm;
5597002Snate@binkert.org                    if (bits(machInst, 8) == 0) {
56012334Sgabeblack@google.com                        vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1);
5616657Snate@binkert.org                        vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1);
5626657Snate@binkert.org                        return new VabsS(machInst,
5637002Snate@binkert.org                                (IntRegIndex)vd, (IntRegIndex)vm);
5647002Snate@binkert.org                    } else {
5656657Snate@binkert.org                        vd = (bits(machInst, 22) << 5) |
5666657Snate@binkert.org                             (bits(machInst, 15, 12) << 1);
5678086SBrad.Beckmann@amd.com                        vm = (bits(machInst, 5) << 5) |
5688086SBrad.Beckmann@amd.com                             (bits(machInst, 3, 0) << 1);
5698086SBrad.Beckmann@amd.com                        return new VabsD(machInst,
5708086SBrad.Beckmann@amd.com                                (IntRegIndex)vd, (IntRegIndex)vm);
5718086SBrad.Beckmann@amd.com                    }
5728086SBrad.Beckmann@amd.com                }
5738086SBrad.Beckmann@amd.com              case 0x1:
5748086SBrad.Beckmann@amd.com                if (opc3 == 1) {
5758086SBrad.Beckmann@amd.com                    uint32_t vd;
5768086SBrad.Beckmann@amd.com                    uint32_t vm;
5778086SBrad.Beckmann@amd.com                    if (bits(machInst, 8) == 0) {
5788086SBrad.Beckmann@amd.com                        vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1);
5798086SBrad.Beckmann@amd.com                        vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1);
5808086SBrad.Beckmann@amd.com                        return new VnegS(machInst,
5818086SBrad.Beckmann@amd.com                                (IntRegIndex)vd, (IntRegIndex)vm);
5828086SBrad.Beckmann@amd.com                    } else {
5838086SBrad.Beckmann@amd.com                        vd = (bits(machInst, 22) << 5) |
5848086SBrad.Beckmann@amd.com                             (bits(machInst, 15, 12) << 1);
5858086SBrad.Beckmann@amd.com                        vm = (bits(machInst, 5) << 5) |
5868086SBrad.Beckmann@amd.com                             (bits(machInst, 3, 0) << 1);
5878086SBrad.Beckmann@amd.com                        return new VnegD(machInst,
5886657Snate@binkert.org                                (IntRegIndex)vd, (IntRegIndex)vm);
5896657Snate@binkert.org                    }
59011283Santhony.gutierrez@amd.com                } else {
5919773Snilay@cs.wisc.edu                    return new WarnUnimplemented("vsqrt", machInst);
59210301Snilay@cs.wisc.edu                }
5936657Snate@binkert.org              case 0x2:
5946657Snate@binkert.org              case 0x3:
5957007Snate@binkert.org                // Between half and single precision.
5967007Snate@binkert.org                return new WarnUnimplemented("vcvtb, vcvtt", machInst);
5977007Snate@binkert.org              case 0x4:
5986657Snate@binkert.org              case 0x5:
5996657Snate@binkert.org                return new WarnUnimplemented("vcmp, vcmpe", machInst);
6006657Snate@binkert.org              case 0x7:
6016657Snate@binkert.org                if (opc3 == 0x3) {
6026657Snate@binkert.org                    // Between double and single precision.
6036657Snate@binkert.org                    return new WarnUnimplemented("vcvt", machInst);
6047007Snate@binkert.org                }
6057007Snate@binkert.org                break;
6067007Snate@binkert.org              case 0x8:
6076657Snate@binkert.org                // Between FP and int.
6086657Snate@binkert.org                return new WarnUnimplemented("vcvt, vcvtr", machInst);
6096657Snate@binkert.org              case 0xa:
6106657Snate@binkert.org              case 0xb:
6116657Snate@binkert.org                // Between FP and fixed point.
6126657Snate@binkert.org                return new WarnUnimplemented("vcvt", machInst);
6136657Snate@binkert.org              case 0xc:
6146657Snate@binkert.org              case 0xd:
6156657Snate@binkert.org                // Between FP and int.
6166657Snate@binkert.org                return new WarnUnimplemented("vcvt, vcvtr", machInst);
6176657Snate@binkert.org              case 0xe:
6186657Snate@binkert.org              case 0xf:
6196657Snate@binkert.org                // Between FP and fixed point.
6206657Snate@binkert.org                return new WarnUnimplemented("vcvt", machInst);
6217805Snilay@cs.wisc.edu            }
6226657Snate@binkert.org            break;
6236657Snate@binkert.org        }
6246657Snate@binkert.org        return new Unknown(machInst);
6257007Snate@binkert.org    }
6267007Snate@binkert.org    '''
6277007Snate@binkert.org}};
6286657Snate@binkert.org
6296657Snate@binkert.orgdef format VfpData() {{
6306657Snate@binkert.org    decode_block = '''
6316657Snate@binkert.org    return decodeVfpData(machInst);
6327007Snate@binkert.org    '''
6336657Snate@binkert.org}};
6346657Snate@binkert.org