data64.isa revision 14128:6ed23d07d0d1
12SN/A// -*- mode:c++ -*-
21762SN/A
32SN/A// Copyright (c) 2011-2013, 2016-2019 ARM Limited
42SN/A// All rights reserved
52SN/A//
62SN/A// The license below extends only to copyright in the software and shall
72SN/A// not be construed as granting a license to any other intellectual
82SN/A// property including but not limited to intellectual property relating
92SN/A// to a hardware implementation of the functionality of the software
102SN/A// licensed hereunder.  You may use the software subject to the license
112SN/A// terms below provided that you ensure that this notice is replicated
122SN/A// unmodified and in its entirety in all distributions of the software,
132SN/A// modified or unmodified, in source code or in binary form.
142SN/A//
152SN/A// Redistribution and use in source and binary forms, with or without
162SN/A// modification, are permitted provided that the following conditions are
172SN/A// met: redistributions of source code must retain the above copyright
182SN/A// notice, this list of conditions and the following disclaimer;
192SN/A// redistributions in binary form must reproduce the above copyright
202SN/A// notice, this list of conditions and the following disclaimer in the
212SN/A// documentation and/or other materials provided with the distribution;
222SN/A// neither the name of the copyright holders nor the names of its
232SN/A// contributors may be used to endorse or promote products derived from
242SN/A// this software without specific prior written permission.
252SN/A//
262SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
272665Ssaidi@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
282665Ssaidi@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
292SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
302SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
312439SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
322984Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33146SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34146SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35146SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36146SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37146SN/A//
38146SN/A// Authors: Gabe Black
391717SN/A
40146SN/Alet {{
411717SN/A
42146SN/A    header_output = ""
431977SN/A    decoder_output = ""
442623SN/A    exec_output = ""
452683Sktlim@umich.edu
461717SN/A    def createCcCode64(carry, overflow):
47146SN/A        code = ""
482683Sktlim@umich.edu        code += '''
493348Sbinkertn@umich.edu            uint16_t _iz, _in;
502036SN/A            _in = bits(resTemp, intWidth - 1);
51146SN/A            _iz = ((resTemp & mask(intWidth)) == 0);
5256SN/A            CondCodesNZ = (_in << 1) | _iz;
5356SN/A            DPRINTF(Arm, "(in, iz) = (%d, %d)\\n", _in, _iz);
5456SN/A        '''
55695SN/A        if overflow and overflow != "none":
562901Ssaidi@eecs.umich.edu            code +=  '''
572SN/A                uint16_t _iv;
581858SN/A                _iv = %s & 1;
593565Sgblack@eecs.umich.edu                CondCodesV = _iv;
603565Sgblack@eecs.umich.edu                DPRINTF(Arm, "(iv) = (%%d)\\n", _iv);
612171SN/A            ''' % overflow
622170SN/A        if carry and carry != "none":
633562Sgblack@eecs.umich.edu            code += '''
64146SN/A                uint16_t _ic;
652462SN/A                _ic = %s & 1;
66146SN/A                CondCodesC = _ic;
672SN/A                DPRINTF(Arm, "(ic) = (%%d)\\n", _ic);
685529Snate@binkert.org            ''' % carry
695529Snate@binkert.org        return code
702SN/A
712449SN/A    oldC = 'CondCodesC'
721355SN/A    oldV = 'CondCodesV'
735529Snate@binkert.org    # Dicts of ways to set the carry flag.
744495Sacolyte@umich.edu    carryCode64 = {
75224SN/A        "none": "none",
761858SN/A        "add": 'findCarry(intWidth, resTemp, Op164, secOp)',
772683Sktlim@umich.edu        "sub": 'findCarry(intWidth, resTemp, Op164, ~secOp)',
782420SN/A        "logic": '0'
795529Snate@binkert.org    }
804997Sgblack@eecs.umich.edu    # Dict of ways to set the overflow flag.
812420SN/A    overflowCode64 = {
822SN/A        "none": "none",
834400Srdreslin@umich.edu        "add": 'findOverflow(intWidth, resTemp, Op164, secOp)',
842672Sktlim@umich.edu        "sub": 'findOverflow(intWidth, resTemp, Op164, ~secOp)',
852683Sktlim@umich.edu        "logic": '0'
862SN/A    }
872SN/A
88334SN/A    immOp2 = "uint64_t secOp M5_VAR_USED = imm;"
89140SN/A    sRegOp2 = "uint64_t secOp M5_VAR_USED = " + \
90334SN/A              "shiftReg64(Op264, shiftAmt, shiftType, intWidth);"
912SN/A    eRegOp2 = "uint64_t secOp M5_VAR_USED = " + \
922SN/A              "extendReg64(Op264, extendType, shiftAmt, intWidth);"
932SN/A
942680Sktlim@umich.edu    def buildDataWork(mnem, code, flagType, suffix, buildCc, buildNonCc,
954377Sgblack@eecs.umich.edu                      base, templateBase):
965169Ssaidi@eecs.umich.edu        code = '''
974377Sgblack@eecs.umich.edu        uint64_t resTemp M5_VAR_USED = 0;
984377Sgblack@eecs.umich.edu        ''' + code
992SN/A        ccCode = createCcCode64(carryCode64[flagType], overflowCode64[flagType])
1002SN/A        Name = mnem.capitalize() + suffix
1012623SN/A        iop = InstObjParams(mnem, Name, base, code)
1022SN/A        iopCc = InstObjParams(mnem + "s", Name + "Cc", base, code + ccCode)
1032SN/A
1042SN/A        def subst(iop):
105180SN/A            global header_output, decoder_output, exec_output
1062623SN/A            header_output += eval(templateBase + "Declare").subst(iop)
107393SN/A            decoder_output += eval(templateBase + "Constructor").subst(iop)
108393SN/A            exec_output += BasicExecute.subst(iop)
109393SN/A
110393SN/A        if buildNonCc:
111384SN/A            subst(iop)
112384SN/A        if buildCc:
113393SN/A            subst(iopCc)
1142623SN/A
115393SN/A    def buildXImmDataInst(mnem, code, flagType = "logic", \
116393SN/A                          buildCc = True, buildNonCc = True, \
117393SN/A                          suffix = "XImm"):
118393SN/A        buildDataWork(mnem, immOp2 + code, flagType, suffix,
119384SN/A                      buildCc, buildNonCc, "DataXImmOp", "DataXImm")
120189SN/A
121189SN/A    def buildXSRegDataInst(mnem, code, flagType = "logic", \
1222623SN/A                           buildCc = True, buildNonCc = True, \
1232SN/A                           suffix = "XSReg"):
124729SN/A        buildDataWork(mnem, sRegOp2 + code, flagType, suffix,
125334SN/A                      buildCc, buildNonCc, "DataXSRegOp", "DataXSReg")
1262SN/A
1272SN/A    def buildXERegDataInst(mnem, code, flagType = "logic", \
1282SN/A                           buildCc = True, buildNonCc = True, \
1292SN/A                           suffix = "XEReg"):
1302SN/A        buildDataWork(mnem, eRegOp2 + code, flagType, suffix,
1312SN/A                      buildCc, buildNonCc, "DataXERegOp", "DataXEReg")
1322SN/A
1332SN/A    def buildDataInst(mnem, code, flagType = "logic",
1342SN/A                      buildCc = True, buildNonCc = True):
1352SN/A        buildXImmDataInst(mnem, code, flagType, buildCc, buildNonCc)
1362SN/A        buildXSRegDataInst(mnem, code, flagType, buildCc, buildNonCc)
1372SN/A        buildXERegDataInst(mnem, code, flagType, buildCc, buildNonCc)
1381001SN/A
1391001SN/A    buildXImmDataInst("adr", "Dest64 = RawPC + imm", buildCc = False);
1401001SN/A    buildXImmDataInst("adrp", "Dest64 = (RawPC & ~mask(12)) + imm",
1411001SN/A                      buildCc = False);
1421001SN/A    buildDataInst("and", "Dest64 = resTemp = Op164 & secOp;")
1432SN/A    buildDataInst("eor", "Dest64 = Op164 ^ secOp;", buildCc = False)
1442SN/A    buildXSRegDataInst("eon", "Dest64 = Op164 ^ ~secOp;", buildCc = False)
1452SN/A    buildDataInst("sub", "Dest64 = resTemp = Op164 - secOp;", "sub")
1462SN/A    buildDataInst("add", "Dest64 = resTemp = Op164 + secOp;", "add")
1472SN/A    buildXSRegDataInst("adc",
1482SN/A            "Dest64 = resTemp = Op164 + secOp + %s;" % oldC, "add")
1492SN/A    buildXSRegDataInst("sbc",
1502SN/A            "Dest64 = resTemp = Op164 - secOp - !%s;" % oldC, "sub")
1512SN/A    buildDataInst("orr", "Dest64 = Op164 | secOp;", buildCc = False)
1522SN/A    buildXSRegDataInst("orn", "Dest64 = Op164 | ~secOp;", buildCc = False)
1532SN/A    buildXSRegDataInst("bic", "Dest64 = resTemp = Op164 & ~secOp;")
1542SN/A
1552SN/A    def buildDataXImmInst(mnem, code, optArgs = []):
1562SN/A        global header_output, decoder_output, exec_output
1572SN/A        classNamePrefix = mnem[0].upper() + mnem[1:]
1582SN/A        templateBase = "DataXImm"
1592SN/A        iop = InstObjParams(mnem, classNamePrefix + "64",
1602390SN/A                            templateBase + "Op", code, optArgs)
1612390SN/A        header_output += eval(templateBase + "Declare").subst(iop)
1622390SN/A        decoder_output += eval(templateBase + "Constructor").subst(iop)
1632390SN/A        exec_output += BasicExecute.subst(iop)
1642390SN/A
1652390SN/A    def buildDataXRegInst(mnem, regOps, code, optArgs = [],
1662390SN/A                          overrideOpClass=None):
1672390SN/A        global header_output, decoder_output, exec_output
1682390SN/A        templateBase = "DataX%dReg" % regOps
1692390SN/A        classNamePrefix = mnem[0].upper() + mnem[1:]
1702390SN/A        if overrideOpClass:
1712390SN/A            iop = InstObjParams(mnem, classNamePrefix + "64",
172385SN/A                                templateBase + "Op",
1732SN/A                                { 'code': code, 'op_class': overrideOpClass},
1742SN/A                                optArgs)
1752SN/A        else:
1762623SN/A            iop = InstObjParams(mnem, classNamePrefix + "64",
177334SN/A                                templateBase + "Op", code, optArgs)
1782361SN/A        header_output += eval(templateBase + "Declare").subst(iop)
1795496Ssaidi@eecs.umich.edu        decoder_output += eval(templateBase + "Constructor").subst(iop)
180334SN/A        exec_output += BasicExecute.subst(iop)
181334SN/A
182334SN/A    buildDataXRegInst("madd", 3, "Dest64 = Op164 + Op264 * Op364",
1832623SN/A        overrideOpClass="IntMultOp")
1842SN/A    buildDataXRegInst("msub", 3, "Dest64 = Op164 - Op264 * Op364",
1855496Ssaidi@eecs.umich.edu        overrideOpClass="IntMultOp")
186921SN/A    buildDataXRegInst("smaddl", 3,
1872915Sktlim@umich.edu        "XDest = XOp1 + sext<32>(WOp2) * sext<32>(WOp3)",
1882915Sktlim@umich.edu        overrideOpClass="IntMultOp")
1892683Sktlim@umich.edu    buildDataXRegInst("smsubl", 3,
1902SN/A        "XDest = XOp1 - sext<32>(WOp2) * sext<32>(WOp3)",
1912SN/A        overrideOpClass="IntMultOp")
1922SN/A    buildDataXRegInst("smulh", 2, '''
1932623SN/A        uint64_t op1H = (int32_t)(XOp1 >> 32);
1942SN/A        uint64_t op1L = (uint32_t)XOp1;
1955496Ssaidi@eecs.umich.edu        uint64_t op2H = (int32_t)(XOp2 >> 32);
196921SN/A        uint64_t op2L = (uint32_t)XOp2;
1972915Sktlim@umich.edu        uint64_t mid1 = ((op1L * op2L) >> 32) + op1H * op2L;
1982915Sktlim@umich.edu        uint64_t mid2 = op1L * op2H;
1992SN/A        uint64_t result = ((uint64_t)(uint32_t)mid1 + (uint32_t)mid2) >> 32;
2002SN/A        result += shiftReg64(mid1, 32, ASR, intWidth);
2012SN/A        result += shiftReg64(mid2, 32, ASR, intWidth);
2022SN/A        XDest = result + op1H * op2H;
2032SN/A    ''', overrideOpClass="IntMultOp")
2042SN/A    buildDataXRegInst("umaddl", 3, "XDest = XOp1 + WOp2 * WOp3",
2052SN/A        overrideOpClass="IntMultOp")
206595SN/A    buildDataXRegInst("umsubl", 3, "XDest = XOp1 - WOp2 * WOp3",
2072623SN/A        overrideOpClass="IntMultOp")
208595SN/A    buildDataXRegInst("umulh", 2, '''
2092390SN/A        uint64_t op1H = (uint32_t)(XOp1 >> 32);
2101080SN/A        uint64_t op1L = (uint32_t)XOp1;
2111080SN/A        uint64_t op2H = (uint32_t)(XOp2 >> 32);
2121080SN/A        uint64_t op2L = (uint32_t)XOp2;
2131080SN/A        uint64_t mid1 = ((op1L * op2L) >> 32) + op1H * op2L;
2141080SN/A        uint64_t mid2 = op1L * op2H;
2151080SN/A        uint64_t result = ((uint64_t)(uint32_t)mid1 + (uint32_t)mid2) >> 32;
2161080SN/A        result += mid1 >> 32;
2171121SN/A        result += mid2 >> 32;
2182107SN/A        XDest = result + op1H * op2H;
2191089SN/A    ''', overrideOpClass="IntMultOp")
2201089SN/A
2211080SN/A    buildDataXRegInst("asrv", 2,
2221080SN/A        "Dest64 = shiftReg64(Op164, Op264, ASR, intWidth)")
2231080SN/A    buildDataXRegInst("lslv", 2,
2241080SN/A        "Dest64 = shiftReg64(Op164, Op264, LSL, intWidth)")
225595SN/A    buildDataXRegInst("lsrv", 2,
2262623SN/A        "Dest64 = shiftReg64(Op164, Op264, LSR, intWidth)")
2272683Sktlim@umich.edu    buildDataXRegInst("rorv", 2,
228595SN/A        "Dest64 = shiftReg64(Op164, Op264, ROR, intWidth)")
2292090SN/A
2302683Sktlim@umich.edu    crcCode = '''
2312683Sktlim@umich.edu    constexpr uint8_t size_bytes = %(sz)d;
232595SN/A    constexpr uint32_t poly = %(polynom)s;
2332205SN/A
2342205SN/A    // Initial value is often a previously evaluated
2352683Sktlim@umich.edu    // crc value hence is always 32bit in CRC32
2362683Sktlim@umich.edu    uint32_t initial_crc = Op164 & 0xFFFFFFFF;
237595SN/A
238595SN/A    uint64_t data = htole(Op264);
2392390SN/A    auto data_buffer = reinterpret_cast<uint8_t*>(&data);
2402423SN/A
2412390SN/A    Dest = crc32<poly>(
242595SN/A        data_buffer,   /* Message register */
243595SN/A        initial_crc,   /* Initial value of the CRC */
244595SN/A        size_bytes     /* Size of the original Message */
2452623SN/A    );
246595SN/A    '''
2472390SN/A    buildDataXRegInst("crc32b", 2,
2481080SN/A        crcCode % {"sz": 1, "polynom": "0x04C11DB7"})
249595SN/A    buildDataXRegInst("crc32h", 2,
2501080SN/A        crcCode % {"sz": 2, "polynom": "0x04C11DB7"})
2511080SN/A    buildDataXRegInst("crc32w", 2,
252595SN/A        crcCode % {"sz": 4, "polynom": "0x04C11DB7"})
2532683Sktlim@umich.edu    buildDataXRegInst("crc32x", 2,
2541080SN/A        crcCode % {"sz": 8, "polynom": "0x04C11DB7"})
2551080SN/A
2561080SN/A    buildDataXRegInst("crc32cb", 2,
2571121SN/A        crcCode % {"sz": 1, "polynom": "0x1EDC6F41"})
2582107SN/A    buildDataXRegInst("crc32ch", 2,
2591089SN/A        crcCode % {"sz": 2, "polynom": "0x1EDC6F41"})
2601080SN/A    buildDataXRegInst("crc32cw", 2,
2611089SN/A        crcCode % {"sz": 4, "polynom": "0x1EDC6F41"})
2621080SN/A    buildDataXRegInst("crc32cx", 2,
2631080SN/A        crcCode % {"sz": 8, "polynom": "0x1EDC6F41"})
2641080SN/A
265595SN/A    buildDataXRegInst("sdiv", 2, '''
2662683Sktlim@umich.edu        int64_t op1 = Op164;
2671080SN/A        int64_t op2 = Op264;
2682090SN/A        if (intWidth == 32) {
2691080SN/A            op1 = sext<32>(op1);
270595SN/A            op2 = sext<32>(op2);
2712683Sktlim@umich.edu        }
2722683Sktlim@umich.edu        Dest64 = op2 == -1 ? -op1 : op2 ? op1 / op2 : 0;
273595SN/A    ''', overrideOpClass="IntDivOp")
2742683Sktlim@umich.edu    buildDataXRegInst("udiv", 2, "Dest64 = Op264 ? Op164 / Op264 : 0",
2751098SN/A        overrideOpClass="IntDivOp")
2761098SN/A
2771098SN/A    buildDataXRegInst("cls", 1, '''
2782683Sktlim@umich.edu        uint64_t op1 = Op164;
2791098SN/A        if (bits(op1, intWidth - 1))
2801098SN/A            op1 ^= mask(intWidth);
2811098SN/A        Dest64 = (op1 == 0) ? intWidth - 1 : (intWidth - 2 - findMsbSet(op1));
2822012SN/A    ''')
2831098SN/A    buildDataXRegInst("clz", 1, '''
2841098SN/A        Dest64 = (Op164 == 0) ? intWidth : (intWidth - 1 - findMsbSet(Op164));
285595SN/A    ''')
2862205SN/A    buildDataXRegInst("rbit", 1, '''
2872205SN/A        Dest64 = reverseBits(Op164, intWidth/8);
2882205SN/A    ''')
289595SN/A    buildDataXRegInst("rev", 1, '''
2902390SN/A        if (intWidth == 32)
2912420SN/A            Dest64 = betole<uint32_t>(Op164);
2922423SN/A        else
2932390SN/A            Dest64 = betole<uint64_t>(Op164);
294595SN/A    ''')
295595SN/A    buildDataXRegInst("rev16", 1, '''
2961858SN/A        int count = intWidth / 16;
2972SN/A        uint64_t result = 0;
2982623SN/A        for (unsigned i = 0; i < count; i++) {
2992SN/A            uint16_t hw = Op164 >> (i * 16);
3002680Sktlim@umich.edu            result |= (uint64_t)betole<uint16_t>(hw) << (i * 16);
3012SN/A        }
3022SN/A        Dest64 = result;
3032SN/A    ''')
3041858SN/A    buildDataXRegInst("rev32", 1, '''
3052SN/A        int count = intWidth / 32;
3065807Snate@binkert.org        uint64_t result = 0;
3072SN/A        for (unsigned i = 0; i < count; i++) {
3085807Snate@binkert.org            uint32_t hw = Op164 >> (i * 32);
3095807Snate@binkert.org            result |= (uint64_t)betole<uint32_t>(hw) << (i * 32);
3102SN/A        }
3115807Snate@binkert.org        Dest64 = result;
3125807Snate@binkert.org    ''')
3132SN/A
3142SN/A    msrMrs64EnabledCheckCode = '''
3152SN/A        // Check for read/write access right
3162SN/A        if (!can%sAArch64SysReg(flat_idx, Scr64, cpsr, xc->tcBase())) {
3172623SN/A            if (flat_idx == MISCREG_DAIF ||
3182SN/A                flat_idx == MISCREG_DC_ZVA_Xt ||
3191858SN/A                flat_idx == MISCREG_DC_CVAC_Xt ||
3205704Snate@binkert.org                flat_idx == MISCREG_DC_CIVAC_Xt
3215647Sgblack@eecs.umich.edu                )
3222SN/A                return std::make_shared<UndefinedInstruction>(
3233520Sgblack@eecs.umich.edu                                    machInst, 0, EC_TRAPPED_MSR_MRS_64,
3245647Sgblack@eecs.umich.edu                                    mnemonic);
3253520Sgblack@eecs.umich.edu            return std::make_shared<UndefinedInstruction>(machInst, false,
3262SN/A                                                          mnemonic);
3272SN/A        }
3282SN/A
3292623SN/A        fault = this->trap(xc->tcBase(), flat_idx, el, imm);
3302SN/A        if (fault != NoFault) return fault;
3312623SN/A    '''
3322623SN/A
3332662Sstever@eecs.umich.edu    mrsCode = '''
3342623SN/A        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
3354514Ssaidi@eecs.umich.edu            flattenRegId(RegId(MiscRegClass, op1)).index();
3364495Sacolyte@umich.edu        CPSR cpsr = Cpsr;
3372623SN/A        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
3383093Sksewell@umich.edu        %s
3394495Sacolyte@umich.edu        XDest = MiscOp1_ud;
3403093Sksewell@umich.edu    ''' % (msrMrs64EnabledCheckCode % ('Read'),)
3413093Sksewell@umich.edu
3424564Sgblack@eecs.umich.edu    mrsIop = InstObjParams("mrs", "Mrs64", "RegMiscRegImmOp64",
3432741Sksewell@umich.edu                           mrsCode,
3442741Sksewell@umich.edu                           ["IsSerializeBefore"])
3452623SN/A    header_output += RegMiscRegOp64Declare.subst(mrsIop)
3464564Sgblack@eecs.umich.edu    decoder_output += RegMiscRegOp64Constructor.subst(mrsIop)
3474564Sgblack@eecs.umich.edu    exec_output += BasicExecute.subst(mrsIop)
3482623SN/A
3492683Sktlim@umich.edu    buildDataXRegInst("mrsNZCV", 1, '''
3502623SN/A        CPSR cpsr = 0;
3512623SN/A        cpsr.nz = CondCodesNZ;
3522623SN/A        cpsr.c = CondCodesC;
3532623SN/A        cpsr.v = CondCodesV;
3542623SN/A        XDest = cpsr;
3552623SN/A    ''')
3562623SN/A
3572623SN/A    msrCode = '''
3582SN/A        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
3592683Sktlim@umich.edu            flattenRegId(RegId(MiscRegClass, dest)).index();
3602427SN/A        CPSR cpsr = Cpsr;
3612683Sktlim@umich.edu        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
3622427SN/A        %s
3632SN/A        MiscDest_ud = XOp1;
3642623SN/A    ''' % (msrMrs64EnabledCheckCode % ('Write'),)
3652623SN/A
3662SN/A    msrIop = InstObjParams("msr", "Msr64", "MiscRegRegImmOp64",
3672623SN/A                           msrCode,
3682623SN/A                           ["IsSerializeAfter", "IsNonSpeculative"])
3694377Sgblack@eecs.umich.edu    header_output += MiscRegRegOp64Declare.subst(msrIop)
3705665Sgblack@eecs.umich.edu    decoder_output += MiscRegRegOp64Constructor.subst(msrIop)
3714377Sgblack@eecs.umich.edu    exec_output += BasicExecute.subst(msrIop)
3725665Sgblack@eecs.umich.edu
3735665Sgblack@eecs.umich.edu
3745665Sgblack@eecs.umich.edu    buildDataXRegInst("msrNZCV", 1, '''
3755665Sgblack@eecs.umich.edu        CPSR cpsr = XOp1;
3765665Sgblack@eecs.umich.edu        CondCodesNZ = cpsr.nz;
3774181Sgblack@eecs.umich.edu        CondCodesC = cpsr.c;
3784181Sgblack@eecs.umich.edu        CondCodesV = cpsr.v;
3794181Sgblack@eecs.umich.edu    ''')
3804182Sgblack@eecs.umich.edu
3814182Sgblack@eecs.umich.edu    msr_check_code = '''
3824182Sgblack@eecs.umich.edu        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
3834593Sgblack@eecs.umich.edu            flattenRegId(RegId(MiscRegClass, dest)).index();
3844593Sgblack@eecs.umich.edu        CPSR cpsr = Cpsr;
3854593Sgblack@eecs.umich.edu        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
3864593Sgblack@eecs.umich.edu        %s
3874593Sgblack@eecs.umich.edu    ''' % (msrMrs64EnabledCheckCode % ('Write'),)
3884377Sgblack@eecs.umich.edu
3894377Sgblack@eecs.umich.edu
3904377Sgblack@eecs.umich.edu    msrdczva_ea_code = msr_check_code
3914377Sgblack@eecs.umich.edu    msrdczva_ea_code += '''
3924377Sgblack@eecs.umich.edu           Request::Flags memAccessFlags = Request::CACHE_BLOCK_ZERO |
3934377Sgblack@eecs.umich.edu               ArmISA::TLB::MustBeOne;
3944377Sgblack@eecs.umich.edu           EA = XBase;
3954377Sgblack@eecs.umich.edu           assert(!(Dczid & 0x10));
3964572Sacolyte@umich.edu           uint64_t op_size = power(2, Dczid + 2);
3974572Sacolyte@umich.edu           EA &= ~(op_size - 1);
3984377Sgblack@eecs.umich.edu
3994377Sgblack@eecs.umich.edu   '''
4004377Sgblack@eecs.umich.edu
4014377Sgblack@eecs.umich.edu    msrDCZVAIop = InstObjParams("dc zva", "Dczva", "SysDC64",
4024181Sgblack@eecs.umich.edu                                { "ea_code" : msrdczva_ea_code,
4034181Sgblack@eecs.umich.edu                                  "memacc_code" : ';',
4044181Sgblack@eecs.umich.edu                                  "use_uops" : 0,
4054539Sgblack@eecs.umich.edu                                  "op_wb" : ";",
4063276Sgblack@eecs.umich.edu                                  "fa_code" : ";"},
4075665Sgblack@eecs.umich.edu                                ['IsStore', 'IsMemRef']);
4083280Sgblack@eecs.umich.edu    header_output += DCStore64Declare.subst(msrDCZVAIop);
4093280Sgblack@eecs.umich.edu    decoder_output += DCStore64Constructor.subst(msrDCZVAIop);
4103276Sgblack@eecs.umich.edu    exec_output += DCStore64Execute.subst(msrDCZVAIop);
4113276Sgblack@eecs.umich.edu    exec_output += DCStore64InitiateAcc.subst(msrDCZVAIop);
4123276Sgblack@eecs.umich.edu    exec_output += Store64CompleteAcc.subst(msrDCZVAIop);
4135665Sgblack@eecs.umich.edu
4143276Sgblack@eecs.umich.edu
4153276Sgblack@eecs.umich.edu    msrdccvau_ea_code = msr_check_code
4164181Sgblack@eecs.umich.edu    msrdccvau_ea_code += '''
4174181Sgblack@eecs.umich.edu           Request::Flags memAccessFlags = Request::CLEAN | Request::DST_POU |
4184181Sgblack@eecs.umich.edu              ArmISA::TLB::MustBeOne;
4194522Ssaidi@eecs.umich.edu           EA = XBase;
4205784Sgblack@eecs.umich.edu           System *sys = xc->tcBase()->getSystemPtr();
4215784Sgblack@eecs.umich.edu           Addr op_size = sys->cacheLineSize();
4225784Sgblack@eecs.umich.edu           EA &= ~(op_size - 1);
4232470SN/A    '''
4244181Sgblack@eecs.umich.edu
4254181Sgblack@eecs.umich.edu    msrDCCVAUIop = InstObjParams("dc cvau", "Dccvau", "SysDC64",
4264522Ssaidi@eecs.umich.edu                                 { "ea_code" : msrdccvau_ea_code,
4272623SN/A                                   "memacc_code" : ';',
4282623SN/A                                   "use_uops" : 0,
4294181Sgblack@eecs.umich.edu                                   "op_wb" : ";", "fa_code" : ";"},
4302623SN/A                                 ['IsStore', 'IsMemRef']);
4314181Sgblack@eecs.umich.edu    header_output += DCStore64Declare.subst(msrDCCVAUIop);
4322623SN/A    decoder_output += DCStore64Constructor.subst(msrDCCVAUIop);
4332623SN/A    exec_output += DCStore64Execute.subst(msrDCCVAUIop);
4342623SN/A    exec_output += DCStore64InitiateAcc.subst(msrDCCVAUIop);
4352623SN/A    exec_output += Store64CompleteAcc.subst(msrDCCVAUIop);
4362623SN/A
4372623SN/A
4385086Sgblack@eecs.umich.edu    msrdccvac_ea_code = msr_check_code
4393577Sgblack@eecs.umich.edu    msrdccvac_ea_code += '''
4402683Sktlim@umich.edu           Request::Flags memAccessFlags = Request::CLEAN | Request::DST_POC |
4415086Sgblack@eecs.umich.edu              ArmISA::TLB::MustBeOne;
4422623SN/A           EA = XBase;
4432683Sktlim@umich.edu           System *sys = xc->tcBase()->getSystemPtr();
4442623SN/A           Addr op_size = sys->cacheLineSize();
4452420SN/A           EA &= ~(op_size - 1);
4462SN/A    '''
4472623SN/A
4482623SN/A    msrDCCVACIop = InstObjParams("dc cvac", "Dccvac", "SysDC64",
4492SN/A                                 { "ea_code" : msrdccvac_ea_code,
4502SN/A                                   "memacc_code" : ';',
4512623SN/A                                   "use_uops" : 0,
4522623SN/A                                   "op_wb" : ";", "fa_code" : ";"},
4532623SN/A                                 ['IsStore', 'IsMemRef']);
4542623SN/A    header_output += DCStore64Declare.subst(msrDCCVACIop);
4552SN/A    decoder_output += DCStore64Constructor.subst(msrDCCVACIop);
4562683Sktlim@umich.edu    exec_output += DCStore64Execute.subst(msrDCCVACIop);
4572644Sstever@eecs.umich.edu    exec_output += DCStore64InitiateAcc.subst(msrDCCVACIop);
4582644Sstever@eecs.umich.edu    exec_output += Store64CompleteAcc.subst(msrDCCVACIop);
4594046Sbinkertn@umich.edu
4604046Sbinkertn@umich.edu
4614046Sbinkertn@umich.edu    msrdccivac_ea_code = msr_check_code
4622644Sstever@eecs.umich.edu    msrdccivac_ea_code += '''
4632623SN/A           Request::Flags memAccessFlags = Request::CLEAN |
4642SN/A              Request::INVALIDATE | Request::DST_POC | ArmISA::TLB::MustBeOne;
4652SN/A           EA = XBase;
4662623SN/A           System *sys = xc->tcBase()->getSystemPtr();
4672623SN/A           Addr op_size = sys->cacheLineSize();
4682623SN/A           EA &= ~(op_size - 1);
4694377Sgblack@eecs.umich.edu    '''
4704377Sgblack@eecs.umich.edu
4712090SN/A    msrDCCIVACIop = InstObjParams("dc civac", "Dccivac", "SysDC64",
4723905Ssaidi@eecs.umich.edu                                  { "ea_code" : msrdccivac_ea_code,
4735120Sgblack@eecs.umich.edu                                    "memacc_code" : ';',
4745665Sgblack@eecs.umich.edu                                    "use_uops" : 0,
4755665Sgblack@eecs.umich.edu                                    "op_wb" : ";", "fa_code" : ";"},
4765281Sgblack@eecs.umich.edu                                  ['IsStore', 'IsMemRef']);
4774377Sgblack@eecs.umich.edu    header_output += DCStore64Declare.subst(msrDCCIVACIop);
4783276Sgblack@eecs.umich.edu    decoder_output += DCStore64Constructor.subst(msrDCCIVACIop);
4794539Sgblack@eecs.umich.edu    exec_output += DCStore64Execute.subst(msrDCCIVACIop);
4805665Sgblack@eecs.umich.edu    exec_output += DCStore64InitiateAcc.subst(msrDCCIVACIop);
4815665Sgblack@eecs.umich.edu    exec_output += Store64CompleteAcc.subst(msrDCCIVACIop);
4825665Sgblack@eecs.umich.edu
4833276Sgblack@eecs.umich.edu
4843276Sgblack@eecs.umich.edu    msrdcivac_ea_code = msr_check_code
4853280Sgblack@eecs.umich.edu    msrdcivac_ea_code += '''
4865665Sgblack@eecs.umich.edu           Request::Flags memAccessFlags = Request::INVALIDATE |
4875665Sgblack@eecs.umich.edu              Request::DST_POC | ArmISA::TLB::MustBeOne;
4883276Sgblack@eecs.umich.edu           EA = XBase;
4893276Sgblack@eecs.umich.edu           HCR hcr = Hcr64;
4905665Sgblack@eecs.umich.edu           SCR scr = Scr64;
4913276Sgblack@eecs.umich.edu           if (el == EL1 && ArmSystem::haveVirtualization(xc->tcBase()) &&
4923280Sgblack@eecs.umich.edu               hcr.vm && (scr.ns || !ArmSystem::haveSecurity(xc->tcBase()))) {
4933276Sgblack@eecs.umich.edu               memAccessFlags = memAccessFlags | Request::CLEAN;
4943276Sgblack@eecs.umich.edu           }
4953280Sgblack@eecs.umich.edu           System *sys = xc->tcBase()->getSystemPtr();
4963276Sgblack@eecs.umich.edu           Addr op_size = sys->cacheLineSize();
4973276Sgblack@eecs.umich.edu           EA &= ~(op_size - 1);
4983276Sgblack@eecs.umich.edu    '''
4993276Sgblack@eecs.umich.edu
5003276Sgblack@eecs.umich.edu    msrDCIVACIop = InstObjParams("dc ivac", "Dcivac", "SysDC64",
5013276Sgblack@eecs.umich.edu                                 { "ea_code" : msrdcivac_ea_code,
5023276Sgblack@eecs.umich.edu                                   "memacc_code" : ';',
5032SN/A                                   "use_uops" : 0,
5042SN/A                                   "op_wb" : ";", "fa_code" : ";"},
5052SN/A                                 ['IsStore', 'IsMemRef']);
5065250Sksewell@umich.edu    header_output += DCStore64Declare.subst(msrDCIVACIop);
5075222Sksewell@umich.edu    decoder_output += DCStore64Constructor.subst(msrDCIVACIop);
5085222Sksewell@umich.edu    exec_output += DCStore64Execute.subst(msrDCIVACIop);
5095222Sksewell@umich.edu    exec_output += DCStore64InitiateAcc.subst(msrDCIVACIop);
5105222Sksewell@umich.edu    exec_output += Store64CompleteAcc.subst(msrDCIVACIop);
5115222Sksewell@umich.edu
5125222Sksewell@umich.edu    def buildMsrImmInst(mnem, inst_name, code):
5135222Sksewell@umich.edu        global header_output, decoder_output, exec_output
5145222Sksewell@umich.edu        msrImmPermission = '''
5155222Sksewell@umich.edu            auto misc_index = (MiscRegIndex) xc->tcBase()->flattenRegId(
5165222Sksewell@umich.edu               RegId(MiscRegClass, dest)).index();
5175222Sksewell@umich.edu
5185222Sksewell@umich.edu            if (!miscRegInfo[misc_index][MISCREG_IMPLEMENTED]) {
5195222Sksewell@umich.edu                    return std::make_shared<UndefinedInstruction>(
5205222Sksewell@umich.edu                                    machInst, false,
5215222Sksewell@umich.edu                                    mnemonic);
5225222Sksewell@umich.edu            }
5235222Sksewell@umich.edu
5245222Sksewell@umich.edu            if (!canWriteAArch64SysReg(misc_index,
5255222Sksewell@umich.edu                Scr64, Cpsr, xc->tcBase())) {
5265222Sksewell@umich.edu
5275222Sksewell@umich.edu                    return std::make_shared<UndefinedInstruction>(
5285222Sksewell@umich.edu                                    machInst, 0, EC_TRAPPED_MSR_MRS_64,
5295222Sksewell@umich.edu                                    mnemonic);
5305222Sksewell@umich.edu            }
5315222Sksewell@umich.edu
5325222Sksewell@umich.edu        '''
5335222Sksewell@umich.edu        msrIop = InstObjParams("msr", inst_name, "MiscRegImmOp64",
5345222Sksewell@umich.edu                               msrImmPermission + code,
5355222Sksewell@umich.edu                               ["IsSerializeAfter", "IsNonSpeculative"])
5365222Sksewell@umich.edu        header_output += MiscRegOp64Declare.subst(msrIop)
5375222Sksewell@umich.edu        decoder_output += MiscRegOp64Constructor.subst(msrIop)
5385222Sksewell@umich.edu        exec_output += BasicExecute.subst(msrIop)
5395250Sksewell@umich.edu
540    buildMsrImmInst("msr", "MsrImm64", '''
541        // Mask and shift immediate (depending on PSTATE field)
542        // before assignment
543        MiscDest_ud = miscRegImm();
544    ''')
545
546    buildMsrImmInst("msr", "MsrImmDAIFSet64", '''
547        CPSR cpsr = Cpsr;
548        cpsr.daif = cpsr.daif | imm;
549        Cpsr = cpsr;
550    ''')
551
552    buildMsrImmInst("msr", "MsrImmDAIFClr64", '''
553        CPSR cpsr = Cpsr;
554        cpsr.daif = cpsr.daif & ~imm;
555        Cpsr = cpsr;
556    ''')
557
558    def buildDataXCompInst(mnem, instType, suffix, code):
559        global header_output, decoder_output, exec_output
560        templateBase = "DataXCond%s" % instType
561        iop = InstObjParams(mnem, mnem.capitalize() + suffix + "64",
562                            templateBase + "Op", code)
563        header_output += eval(templateBase + "Declare").subst(iop)
564        decoder_output += eval(templateBase + "Constructor").subst(iop)
565        exec_output += BasicExecute.subst(iop)
566
567    def buildDataXCondImmInst(mnem, code):
568        buildDataXCompInst(mnem, "CompImm", "Imm", code)
569    def buildDataXCondRegInst(mnem, code):
570        buildDataXCompInst(mnem, "CompReg", "Reg", code)
571    def buildDataXCondSelInst(mnem, code):
572        buildDataXCompInst(mnem, "Sel", "", code)
573
574    def condCompCode(flagType, op, imm):
575        ccCode = createCcCode64(carryCode64[flagType], overflowCode64[flagType])
576        opDecl = "uint64_t secOp M5_VAR_USED = imm;"
577        if not imm:
578            opDecl = "uint64_t secOp M5_VAR_USED = Op264;"
579        return opDecl + '''
580            if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) {
581                uint64_t resTemp = Op164 ''' + op + ''' secOp;
582        ''' + ccCode + '''
583            } else {
584                CondCodesNZ = (defCc >> 2) & 0x3;
585                CondCodesC = (defCc >> 1) & 0x1;
586                CondCodesV = defCc & 0x1;
587            }
588        '''
589
590    buildDataXCondImmInst("ccmn", condCompCode("add", "+", True))
591    buildDataXCondImmInst("ccmp", condCompCode("sub", "-", True))
592    buildDataXCondRegInst("ccmn", condCompCode("add", "+", False))
593    buildDataXCondRegInst("ccmp", condCompCode("sub", "-", False))
594
595    condSelCode = '''
596        if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) {
597            Dest64 = Op164;
598        } else {
599            Dest64 = %(altVal)s;
600        }
601    '''
602    buildDataXCondSelInst("csel", condSelCode % {"altVal" : "Op264"})
603    buildDataXCondSelInst("csinc", condSelCode % {"altVal" : "Op264 + 1"})
604    buildDataXCondSelInst("csinv", condSelCode % {"altVal" : "~Op264"})
605    buildDataXCondSelInst("csneg", condSelCode % {"altVal" : "-Op264"})
606}};
607