data64.isa revision 12507
14188Sgblack@eecs.umich.edu// -*- mode:c++ -*-
24188Sgblack@eecs.umich.edu
34188Sgblack@eecs.umich.edu// Copyright (c) 2011-2013, 2016-2018 ARM Limited
44188Sgblack@eecs.umich.edu// All rights reserved
54188Sgblack@eecs.umich.edu//
64188Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall
74188Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual
84188Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating
94188Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software
104188Sgblack@eecs.umich.edu// licensed hereunder.  You may use the software subject to the license
114188Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated
124188Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software,
134188Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form.
144188Sgblack@eecs.umich.edu//
154188Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
164188Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
174188Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
184188Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
194188Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
204188Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
214188Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
224188Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
234188Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
244188Sgblack@eecs.umich.edu// this software without specific prior written permission.
254188Sgblack@eecs.umich.edu//
264188Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
274188Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
284188Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
294188Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
304188Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
314188Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3211794Sbrandon.potter@amd.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
334188Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
344188Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3511851Sbrandon.potter@amd.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
364188Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
374188Sgblack@eecs.umich.edu//
384188Sgblack@eecs.umich.edu// Authors: Gabe Black
394188Sgblack@eecs.umich.edu
404188Sgblack@eecs.umich.edulet {{
414188Sgblack@eecs.umich.edu
4213995Sbrandon.potter@amd.com    header_output = ""
434188Sgblack@eecs.umich.edu    decoder_output = ""
446701Sgblack@eecs.umich.edu    exec_output = ""
4513995Sbrandon.potter@amd.com
466701Sgblack@eecs.umich.edu    def createCcCode64(carry, overflow):
474188Sgblack@eecs.umich.edu        code = ""
484188Sgblack@eecs.umich.edu        code += '''
499149SAli.Saidi@ARM.com            uint16_t _iz, _in;
5014014Sciro.santilli@arm.com            _in = bits(resTemp, intWidth - 1);
514188Sgblack@eecs.umich.edu            _iz = ((resTemp & mask(intWidth)) == 0);
524188Sgblack@eecs.umich.edu            CondCodesNZ = (_in << 1) | _iz;
534188Sgblack@eecs.umich.edu            DPRINTF(Arm, "(in, iz) = (%d, %d)\\n", _in, _iz);
5414024Sgabeblack@google.com        '''
554188Sgblack@eecs.umich.edu        if overflow and overflow != "none":
564188Sgblack@eecs.umich.edu            code +=  '''
574188Sgblack@eecs.umich.edu                uint16_t _iv;
584188Sgblack@eecs.umich.edu                _iv = %s & 1;
594188Sgblack@eecs.umich.edu                CondCodesV = _iv;
607741Sgblack@eecs.umich.edu                DPRINTF(Arm, "(iv) = (%%d)\\n", _iv);
6113995Sbrandon.potter@amd.com            ''' % overflow
624188Sgblack@eecs.umich.edu        if carry and carry != "none":
6313583Sgabeblack@google.com            code += '''
646701Sgblack@eecs.umich.edu                uint16_t _ic;
6513995Sbrandon.potter@amd.com                _ic = %s & 1;
666701Sgblack@eecs.umich.edu                CondCodesC = _ic;
676701Sgblack@eecs.umich.edu                DPRINTF(Arm, "(ic) = (%%d)\\n", _ic);
686701Sgblack@eecs.umich.edu            ''' % carry
697741Sgblack@eecs.umich.edu        return code
707741Sgblack@eecs.umich.edu
717741Sgblack@eecs.umich.edu    oldC = 'CondCodesC'
7213583Sgabeblack@google.com    oldV = 'CondCodesV'
7313583Sgabeblack@google.com    # Dicts of ways to set the carry flag.
7414024Sgabeblack@google.com    carryCode64 = {
754188Sgblack@eecs.umich.edu        "none": "none",
767741Sgblack@eecs.umich.edu        "add": 'findCarry(intWidth, resTemp, Op164, secOp)',
777741Sgblack@eecs.umich.edu        "sub": 'findCarry(intWidth, resTemp, Op164, ~secOp)',
7813583Sgabeblack@google.com        "logic": '0'
7913583Sgabeblack@google.com    }
8014024Sgabeblack@google.com    # Dict of ways to set the overflow flag.
814188Sgblack@eecs.umich.edu    overflowCode64 = {
827741Sgblack@eecs.umich.edu        "none": "none",
837741Sgblack@eecs.umich.edu        "add": 'findOverflow(intWidth, resTemp, Op164, secOp)',
8413583Sgabeblack@google.com        "sub": 'findOverflow(intWidth, resTemp, Op164, ~secOp)',
8513583Sgabeblack@google.com        "logic": '0'
8614024Sgabeblack@google.com    }
874188Sgblack@eecs.umich.edu
884188Sgblack@eecs.umich.edu    immOp2 = "uint64_t secOp M5_VAR_USED = imm;"
894188Sgblack@eecs.umich.edu    sRegOp2 = "uint64_t secOp M5_VAR_USED = " + \
904188Sgblack@eecs.umich.edu              "shiftReg64(Op264, shiftAmt, shiftType, intWidth);"
914188Sgblack@eecs.umich.edu    eRegOp2 = "uint64_t secOp M5_VAR_USED = " + \
924188Sgblack@eecs.umich.edu              "extendReg64(Op264, extendType, shiftAmt, intWidth);"
937741Sgblack@eecs.umich.edu
944188Sgblack@eecs.umich.edu    def buildDataWork(mnem, code, flagType, suffix, buildCc, buildNonCc,
9513570Sbrandon.potter@amd.com                      base, templateBase):
9613570Sbrandon.potter@amd.com        code = '''
977741Sgblack@eecs.umich.edu        uint64_t resTemp M5_VAR_USED = 0;
984188Sgblack@eecs.umich.edu        ''' + code
997741Sgblack@eecs.umich.edu        ccCode = createCcCode64(carryCode64[flagType], overflowCode64[flagType])
1007741Sgblack@eecs.umich.edu        Name = mnem.capitalize() + suffix
1014188Sgblack@eecs.umich.edu        iop = InstObjParams(mnem, Name, base, code)
1024188Sgblack@eecs.umich.edu        iopCc = InstObjParams(mnem + "s", Name + "Cc", base, code + ccCode)
1034188Sgblack@eecs.umich.edu
1044188Sgblack@eecs.umich.edu        def subst(iop):
1057741Sgblack@eecs.umich.edu            global header_output, decoder_output, exec_output
1064188Sgblack@eecs.umich.edu            header_output += eval(templateBase + "Declare").subst(iop)
1074188Sgblack@eecs.umich.edu            decoder_output += eval(templateBase + "Constructor").subst(iop)
1087741Sgblack@eecs.umich.edu            exec_output += BasicExecute.subst(iop)
1095748SSteve.Reinhardt@amd.com
1107741Sgblack@eecs.umich.edu        if buildNonCc:
1117741Sgblack@eecs.umich.edu            subst(iop)
1124188Sgblack@eecs.umich.edu        if buildCc:
1134188Sgblack@eecs.umich.edu            subst(iopCc)
1144188Sgblack@eecs.umich.edu
1157741Sgblack@eecs.umich.edu    def buildXImmDataInst(mnem, code, flagType = "logic", \
1167741Sgblack@eecs.umich.edu                          buildCc = True, buildNonCc = True, \
1174188Sgblack@eecs.umich.edu                          suffix = "XImm"):
1184188Sgblack@eecs.umich.edu        buildDataWork(mnem, immOp2 + code, flagType, suffix,
1194188Sgblack@eecs.umich.edu                      buildCc, buildNonCc, "DataXImmOp", "DataXImm")
1207741Sgblack@eecs.umich.edu
1217741Sgblack@eecs.umich.edu    def buildXSRegDataInst(mnem, code, flagType = "logic", \
1224188Sgblack@eecs.umich.edu                           buildCc = True, buildNonCc = True, \
1234188Sgblack@eecs.umich.edu                           suffix = "XSReg"):
1244188Sgblack@eecs.umich.edu        buildDataWork(mnem, sRegOp2 + code, flagType, suffix,
1257741Sgblack@eecs.umich.edu                      buildCc, buildNonCc, "DataXSRegOp", "DataXSReg")
1267741Sgblack@eecs.umich.edu
1274188Sgblack@eecs.umich.edu    def buildXERegDataInst(mnem, code, flagType = "logic", \
1284188Sgblack@eecs.umich.edu                           buildCc = True, buildNonCc = True, \
1297741Sgblack@eecs.umich.edu                           suffix = "XEReg"):
1304188Sgblack@eecs.umich.edu        buildDataWork(mnem, eRegOp2 + code, flagType, suffix,
1317741Sgblack@eecs.umich.edu                      buildCc, buildNonCc, "DataXERegOp", "DataXEReg")
1324188Sgblack@eecs.umich.edu
1334188Sgblack@eecs.umich.edu    def buildDataInst(mnem, code, flagType = "logic",
1344188Sgblack@eecs.umich.edu                      buildCc = True, buildNonCc = True):
1354264Sgblack@eecs.umich.edu        buildXImmDataInst(mnem, code, flagType, buildCc, buildNonCc)
1364188Sgblack@eecs.umich.edu        buildXSRegDataInst(mnem, code, flagType, buildCc, buildNonCc)
1377741Sgblack@eecs.umich.edu        buildXERegDataInst(mnem, code, flagType, buildCc, buildNonCc)
1387741Sgblack@eecs.umich.edu
1397741Sgblack@eecs.umich.edu    buildXImmDataInst("adr", "Dest64 = RawPC + imm", buildCc = False);
1407741Sgblack@eecs.umich.edu    buildXImmDataInst("adrp", "Dest64 = (RawPC & ~mask(12)) + imm",
1417741Sgblack@eecs.umich.edu                      buildCc = False);
1427741Sgblack@eecs.umich.edu    buildDataInst("and", "Dest64 = resTemp = Op164 & secOp;")
1434188Sgblack@eecs.umich.edu    buildDataInst("eor", "Dest64 = Op164 ^ secOp;", buildCc = False)
1444188Sgblack@eecs.umich.edu    buildXSRegDataInst("eon", "Dest64 = Op164 ^ ~secOp;", buildCc = False)
1454188Sgblack@eecs.umich.edu    buildDataInst("sub", "Dest64 = resTemp = Op164 - secOp;", "sub")
1464188Sgblack@eecs.umich.edu    buildDataInst("add", "Dest64 = resTemp = Op164 + secOp;", "add")
1477741Sgblack@eecs.umich.edu    buildXSRegDataInst("adc",
1487741Sgblack@eecs.umich.edu            "Dest64 = resTemp = Op164 + secOp + %s;" % oldC, "add")
1494188Sgblack@eecs.umich.edu    buildXSRegDataInst("sbc",
1507741Sgblack@eecs.umich.edu            "Dest64 = resTemp = Op164 - secOp - !%s;" % oldC, "sub")
1517741Sgblack@eecs.umich.edu    buildDataInst("orr", "Dest64 = Op164 | secOp;", buildCc = False)
1527741Sgblack@eecs.umich.edu    buildXSRegDataInst("orn", "Dest64 = Op164 | ~secOp;", buildCc = False)
1534188Sgblack@eecs.umich.edu    buildXSRegDataInst("bic", "Dest64 = resTemp = Op164 & ~secOp;")
1544188Sgblack@eecs.umich.edu
1554188Sgblack@eecs.umich.edu    def buildDataXImmInst(mnem, code, optArgs = []):
1564188Sgblack@eecs.umich.edu        global header_output, decoder_output, exec_output
1577741Sgblack@eecs.umich.edu        classNamePrefix = mnem[0].upper() + mnem[1:]
1584188Sgblack@eecs.umich.edu        templateBase = "DataXImm"
1597741Sgblack@eecs.umich.edu        iop = InstObjParams(mnem, classNamePrefix + "64",
1607741Sgblack@eecs.umich.edu                            templateBase + "Op", code, optArgs)
1614188Sgblack@eecs.umich.edu        header_output += eval(templateBase + "Declare").subst(iop)
1624188Sgblack@eecs.umich.edu        decoder_output += eval(templateBase + "Constructor").subst(iop)
1634188Sgblack@eecs.umich.edu        exec_output += BasicExecute.subst(iop)
1644188Sgblack@eecs.umich.edu
1654188Sgblack@eecs.umich.edu    def buildDataXRegInst(mnem, regOps, code, optArgs = [],
1666109Ssanchezd@stanford.edu                          overrideOpClass=None):
1674188Sgblack@eecs.umich.edu        global header_output, decoder_output, exec_output
1684188Sgblack@eecs.umich.edu        templateBase = "DataX%dReg" % regOps
1697741Sgblack@eecs.umich.edu        classNamePrefix = mnem[0].upper() + mnem[1:]
1704188Sgblack@eecs.umich.edu        if overrideOpClass:
1717741Sgblack@eecs.umich.edu            iop = InstObjParams(mnem, classNamePrefix + "64",
1727741Sgblack@eecs.umich.edu                                templateBase + "Op",
1734188Sgblack@eecs.umich.edu                                { 'code': code, 'op_class': overrideOpClass},
1747741Sgblack@eecs.umich.edu                                optArgs)
1757741Sgblack@eecs.umich.edu        else:
1767741Sgblack@eecs.umich.edu            iop = InstObjParams(mnem, classNamePrefix + "64",
1777741Sgblack@eecs.umich.edu                                templateBase + "Op", code, optArgs)
1787741Sgblack@eecs.umich.edu        header_output += eval(templateBase + "Declare").subst(iop)
1794188Sgblack@eecs.umich.edu        decoder_output += eval(templateBase + "Constructor").subst(iop)
1807741Sgblack@eecs.umich.edu        exec_output += BasicExecute.subst(iop)
1814188Sgblack@eecs.umich.edu
1824188Sgblack@eecs.umich.edu    buildDataXRegInst("madd", 3, "Dest64 = Op164 + Op264 * Op364",
1834188Sgblack@eecs.umich.edu        overrideOpClass="IntMultOp")
1844188Sgblack@eecs.umich.edu    buildDataXRegInst("msub", 3, "Dest64 = Op164 - Op264 * Op364",
1857741Sgblack@eecs.umich.edu        overrideOpClass="IntMultOp")
1864188Sgblack@eecs.umich.edu    buildDataXRegInst("smaddl", 3,
1874188Sgblack@eecs.umich.edu        "XDest = XOp1 + sext<32>(WOp2) * sext<32>(WOp3)",
1887741Sgblack@eecs.umich.edu        overrideOpClass="IntMultOp")
1894188Sgblack@eecs.umich.edu    buildDataXRegInst("smsubl", 3,
1904188Sgblack@eecs.umich.edu        "XDest = XOp1 - sext<32>(WOp2) * sext<32>(WOp3)",
1914188Sgblack@eecs.umich.edu        overrideOpClass="IntMultOp")
1927741Sgblack@eecs.umich.edu    buildDataXRegInst("smulh", 2, '''
1937741Sgblack@eecs.umich.edu        uint64_t op1H = (int32_t)(XOp1 >> 32);
1947741Sgblack@eecs.umich.edu        uint64_t op1L = (uint32_t)XOp1;
1957741Sgblack@eecs.umich.edu        uint64_t op2H = (int32_t)(XOp2 >> 32);
1967741Sgblack@eecs.umich.edu        uint64_t op2L = (uint32_t)XOp2;
1974188Sgblack@eecs.umich.edu        uint64_t mid1 = ((op1L * op2L) >> 32) + op1H * op2L;
1987741Sgblack@eecs.umich.edu        uint64_t mid2 = op1L * op2H;
1994188Sgblack@eecs.umich.edu        uint64_t result = ((uint64_t)(uint32_t)mid1 + (uint32_t)mid2) >> 32;
2004188Sgblack@eecs.umich.edu        result += shiftReg64(mid1, 32, ASR, intWidth);
2014188Sgblack@eecs.umich.edu        result += shiftReg64(mid2, 32, ASR, intWidth);
2026109Ssanchezd@stanford.edu        XDest = result + op1H * op2H;
2034188Sgblack@eecs.umich.edu    ''', overrideOpClass="IntMultOp")
2044188Sgblack@eecs.umich.edu    buildDataXRegInst("umaddl", 3, "XDest = XOp1 + WOp2 * WOp3",
2054188Sgblack@eecs.umich.edu        overrideOpClass="IntMultOp")
2064188Sgblack@eecs.umich.edu    buildDataXRegInst("umsubl", 3, "XDest = XOp1 - WOp2 * WOp3",
2077741Sgblack@eecs.umich.edu        overrideOpClass="IntMultOp")
2087741Sgblack@eecs.umich.edu    buildDataXRegInst("umulh", 2, '''
2097741Sgblack@eecs.umich.edu        uint64_t op1H = (uint32_t)(XOp1 >> 32);
2104188Sgblack@eecs.umich.edu        uint64_t op1L = (uint32_t)XOp1;
2115513SMichael.Adler@intel.com        uint64_t op2H = (uint32_t)(XOp2 >> 32);
2124188Sgblack@eecs.umich.edu        uint64_t op2L = (uint32_t)XOp2;
2134188Sgblack@eecs.umich.edu        uint64_t mid1 = ((op1L * op2L) >> 32) + op1H * op2L;
2147741Sgblack@eecs.umich.edu        uint64_t mid2 = op1L * op2H;
2157741Sgblack@eecs.umich.edu        uint64_t result = ((uint64_t)(uint32_t)mid1 + (uint32_t)mid2) >> 32;
2164188Sgblack@eecs.umich.edu        result += mid1 >> 32;
2174188Sgblack@eecs.umich.edu        result += mid2 >> 32;
2187741Sgblack@eecs.umich.edu        XDest = result + op1H * op2H;
2197741Sgblack@eecs.umich.edu    ''', overrideOpClass="IntMultOp")
2204236Sgblack@eecs.umich.edu
2214188Sgblack@eecs.umich.edu    buildDataXRegInst("asrv", 2,
2224188Sgblack@eecs.umich.edu        "Dest64 = shiftReg64(Op164, Op264, ASR, intWidth)")
2234188Sgblack@eecs.umich.edu    buildDataXRegInst("lslv", 2,
2244188Sgblack@eecs.umich.edu        "Dest64 = shiftReg64(Op164, Op264, LSL, intWidth)")
2254188Sgblack@eecs.umich.edu    buildDataXRegInst("lsrv", 2,
2264188Sgblack@eecs.umich.edu        "Dest64 = shiftReg64(Op164, Op264, LSR, intWidth)")
2274188Sgblack@eecs.umich.edu    buildDataXRegInst("rorv", 2,
2287741Sgblack@eecs.umich.edu        "Dest64 = shiftReg64(Op164, Op264, ROR, intWidth)")
2294188Sgblack@eecs.umich.edu
2307741Sgblack@eecs.umich.edu    crcCode = '''
2314188Sgblack@eecs.umich.edu    constexpr uint8_t size_bytes = %(sz)d;
2327741Sgblack@eecs.umich.edu    constexpr uint32_t poly = %(polynom)s;
2334188Sgblack@eecs.umich.edu
2347741Sgblack@eecs.umich.edu    // Initial value is often a previously evaluated
2354188Sgblack@eecs.umich.edu    // crc value hence is always 32bit in CRC32
2364188Sgblack@eecs.umich.edu    uint32_t initial_crc = Op164 & 0xFFFFFFFF;
2374188Sgblack@eecs.umich.edu
2384188Sgblack@eecs.umich.edu    uint64_t data = htole(Op264);
2397741Sgblack@eecs.umich.edu    auto data_buffer = reinterpret_cast<uint8_t*>(&data);
2404188Sgblack@eecs.umich.edu
2414188Sgblack@eecs.umich.edu    Dest = crc32<poly>(
2424188Sgblack@eecs.umich.edu        data_buffer,   /* Message register */
2434188Sgblack@eecs.umich.edu        initial_crc,   /* Initial value of the CRC */
2444188Sgblack@eecs.umich.edu        size_bytes     /* Size of the original Message */
2454188Sgblack@eecs.umich.edu    );
24610495Snilay@cs.wisc.edu    '''
2474188Sgblack@eecs.umich.edu    buildDataXRegInst("crc32b", 2,
2484188Sgblack@eecs.umich.edu        crcCode % {"sz": 1, "polynom": "0x04C11DB7"})
2494188Sgblack@eecs.umich.edu    buildDataXRegInst("crc32h", 2,
2504188Sgblack@eecs.umich.edu        crcCode % {"sz": 2, "polynom": "0x04C11DB7"})
2514188Sgblack@eecs.umich.edu    buildDataXRegInst("crc32w", 2,
2524188Sgblack@eecs.umich.edu        crcCode % {"sz": 4, "polynom": "0x04C11DB7"})
2534188Sgblack@eecs.umich.edu    buildDataXRegInst("crc32x", 2,
2547741Sgblack@eecs.umich.edu        crcCode % {"sz": 8, "polynom": "0x04C11DB7"})
2557741Sgblack@eecs.umich.edu
2564188Sgblack@eecs.umich.edu    buildDataXRegInst("crc32cb", 2,
2574188Sgblack@eecs.umich.edu        crcCode % {"sz": 1, "polynom": "0x1EDC6F41"})
2584188Sgblack@eecs.umich.edu    buildDataXRegInst("crc32ch", 2,
2594188Sgblack@eecs.umich.edu        crcCode % {"sz": 2, "polynom": "0x1EDC6F41"})
2604188Sgblack@eecs.umich.edu    buildDataXRegInst("crc32cw", 2,
2617741Sgblack@eecs.umich.edu        crcCode % {"sz": 4, "polynom": "0x1EDC6F41"})
2627741Sgblack@eecs.umich.edu    buildDataXRegInst("crc32cx", 2,
2637741Sgblack@eecs.umich.edu        crcCode % {"sz": 8, "polynom": "0x1EDC6F41"})
2644188Sgblack@eecs.umich.edu
2654188Sgblack@eecs.umich.edu    buildDataXRegInst("sdiv", 2, '''
26610495Snilay@cs.wisc.edu        int64_t op1 = Op164;
2674188Sgblack@eecs.umich.edu        int64_t op2 = Op264;
2684188Sgblack@eecs.umich.edu        if (intWidth == 32) {
2697741Sgblack@eecs.umich.edu            op1 = sext<32>(op1);
2704188Sgblack@eecs.umich.edu            op2 = sext<32>(op2);
2714188Sgblack@eecs.umich.edu        }
2727741Sgblack@eecs.umich.edu        Dest64 = op2 == -1 ? -op1 : op2 ? op1 / op2 : 0;
2734188Sgblack@eecs.umich.edu    ''', overrideOpClass="IntDivOp")
2744188Sgblack@eecs.umich.edu    buildDataXRegInst("udiv", 2, "Dest64 = Op264 ? Op164 / Op264 : 0",
2754188Sgblack@eecs.umich.edu        overrideOpClass="IntDivOp")
2764188Sgblack@eecs.umich.edu
2777741Sgblack@eecs.umich.edu    buildDataXRegInst("cls", 1, '''
2787741Sgblack@eecs.umich.edu        uint64_t op1 = Op164;
2797741Sgblack@eecs.umich.edu        if (bits(op1, intWidth - 1))
2807741Sgblack@eecs.umich.edu            op1 ^= mask(intWidth);
2814188Sgblack@eecs.umich.edu        Dest64 = (op1 == 0) ? intWidth - 1 : (intWidth - 2 - findMsbSet(op1));
2827741Sgblack@eecs.umich.edu    ''')
2834188Sgblack@eecs.umich.edu    buildDataXRegInst("clz", 1, '''
2844188Sgblack@eecs.umich.edu        Dest64 = (Op164 == 0) ? intWidth : (intWidth - 1 - findMsbSet(Op164));
2857741Sgblack@eecs.umich.edu    ''')
2867741Sgblack@eecs.umich.edu    buildDataXRegInst("rbit", 1, '''
2877741Sgblack@eecs.umich.edu        Dest64 = reverseBits(Op164, intWidth/8);
2887741Sgblack@eecs.umich.edu    ''')
2894188Sgblack@eecs.umich.edu    buildDataXRegInst("rev", 1, '''
2907741Sgblack@eecs.umich.edu        if (intWidth == 32)
2914188Sgblack@eecs.umich.edu            Dest64 = betole<uint32_t>(Op164);
2924188Sgblack@eecs.umich.edu        else
2934188Sgblack@eecs.umich.edu            Dest64 = betole<uint64_t>(Op164);
2944188Sgblack@eecs.umich.edu    ''')
2954188Sgblack@eecs.umich.edu    buildDataXRegInst("rev16", 1, '''
2964188Sgblack@eecs.umich.edu        int count = intWidth / 16;
2977741Sgblack@eecs.umich.edu        uint64_t result = 0;
2987741Sgblack@eecs.umich.edu        for (unsigned i = 0; i < count; i++) {
2997741Sgblack@eecs.umich.edu            uint16_t hw = Op164 >> (i * 16);
3007741Sgblack@eecs.umich.edu            result |= (uint64_t)betole<uint16_t>(hw) << (i * 16);
3017741Sgblack@eecs.umich.edu        }
3027741Sgblack@eecs.umich.edu        Dest64 = result;
3037741Sgblack@eecs.umich.edu    ''')
3047741Sgblack@eecs.umich.edu    buildDataXRegInst("rev32", 1, '''
3054188Sgblack@eecs.umich.edu        int count = intWidth / 32;
3067741Sgblack@eecs.umich.edu        uint64_t result = 0;
3077741Sgblack@eecs.umich.edu        for (unsigned i = 0; i < count; i++) {
3087741Sgblack@eecs.umich.edu            uint32_t hw = Op164 >> (i * 32);
30911886Sbrandon.potter@amd.com            result |= (uint64_t)betole<uint32_t>(hw) << (i * 32);
3107741Sgblack@eecs.umich.edu        }
3117741Sgblack@eecs.umich.edu        Dest64 = result;
3127741Sgblack@eecs.umich.edu    ''')
3134188Sgblack@eecs.umich.edu
3147741Sgblack@eecs.umich.edu    msrMrs64EnabledCheckCode = '''
3154188Sgblack@eecs.umich.edu        // Check for read/write access right
3167741Sgblack@eecs.umich.edu        if (!can%sAArch64SysReg(flat_idx, Scr64, cpsr, xc->tcBase())) {
3177741Sgblack@eecs.umich.edu            if (flat_idx == MISCREG_DAIF ||
3187741Sgblack@eecs.umich.edu                flat_idx == MISCREG_DC_ZVA_Xt ||
3194188Sgblack@eecs.umich.edu                flat_idx == MISCREG_DC_CVAC_Xt ||
3207741Sgblack@eecs.umich.edu                flat_idx == MISCREG_DC_CIVAC_Xt ||
3217741Sgblack@eecs.umich.edu                flat_idx == MISCREG_DC_IVAC_Xt
3227741Sgblack@eecs.umich.edu                )
3234264Sgblack@eecs.umich.edu                return std::make_shared<UndefinedInstruction>(
3244188Sgblack@eecs.umich.edu                                    machInst, 0, EC_TRAPPED_MSR_MRS_64,
3254188Sgblack@eecs.umich.edu                                    mnemonic);
3264188Sgblack@eecs.umich.edu            return std::make_shared<UndefinedInstruction>(machInst, false,
3274188Sgblack@eecs.umich.edu                                                          mnemonic);
3284188Sgblack@eecs.umich.edu        }
3294188Sgblack@eecs.umich.edu
3304188Sgblack@eecs.umich.edu        // Check for traps to supervisor (FP/SIMD regs)
3317741Sgblack@eecs.umich.edu        if (el <= EL1 && msrMrs64TrapToSup(flat_idx, el, Cpacr64))
3324188Sgblack@eecs.umich.edu            return std::make_shared<SupervisorTrap>(machInst, 0x1E00000,
3337741Sgblack@eecs.umich.edu                                                    EC_TRAPPED_SIMD_FP);
3347741Sgblack@eecs.umich.edu
3357741Sgblack@eecs.umich.edu        bool is_vfp_neon = false;
3367741Sgblack@eecs.umich.edu
3374188Sgblack@eecs.umich.edu        // Check for traps to hypervisor
3387741Sgblack@eecs.umich.edu        if ((ArmSystem::haveVirtualization(xc->tcBase()) && el <= EL2) &&
3397741Sgblack@eecs.umich.edu            msrMrs64TrapToHyp(flat_idx, el, %s, CptrEl264, Hcr64, &is_vfp_neon)) {
3407741Sgblack@eecs.umich.edu            return std::make_shared<HypervisorTrap>(
3414188Sgblack@eecs.umich.edu                machInst, is_vfp_neon ? 0x1E00000 : imm,
3427741Sgblack@eecs.umich.edu                is_vfp_neon ? EC_TRAPPED_SIMD_FP : EC_TRAPPED_MSR_MRS_64);
3437741Sgblack@eecs.umich.edu        }
3447741Sgblack@eecs.umich.edu
3454188Sgblack@eecs.umich.edu        // Check for traps to secure monitor
3467741Sgblack@eecs.umich.edu        if ((ArmSystem::haveSecurity(xc->tcBase()) && el <= EL3) &&
3474188Sgblack@eecs.umich.edu            msrMrs64TrapToMon(flat_idx, CptrEl364, el, &is_vfp_neon)) {
3484188Sgblack@eecs.umich.edu            return std::make_shared<SecureMonitorTrap>(
3494188Sgblack@eecs.umich.edu                machInst,
3504188Sgblack@eecs.umich.edu                is_vfp_neon ? 0x1E00000 : imm,
3517741Sgblack@eecs.umich.edu                is_vfp_neon ? EC_TRAPPED_SIMD_FP : EC_TRAPPED_MSR_MRS_64);
3524188Sgblack@eecs.umich.edu        }
3534188Sgblack@eecs.umich.edu    '''
3547741Sgblack@eecs.umich.edu
3554188Sgblack@eecs.umich.edu    mrsCode = '''
3564188Sgblack@eecs.umich.edu        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
3574188Sgblack@eecs.umich.edu            flattenRegId(RegId(MiscRegClass, op1)).index();
3584188Sgblack@eecs.umich.edu        CPSR cpsr = Cpsr;
3594188Sgblack@eecs.umich.edu        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
3604188Sgblack@eecs.umich.edu        %s
3614188Sgblack@eecs.umich.edu        XDest = MiscOp1_ud;
3627741Sgblack@eecs.umich.edu    ''' % (msrMrs64EnabledCheckCode % ('Read', 'true'),)
3634188Sgblack@eecs.umich.edu
3644188Sgblack@eecs.umich.edu    mrsIop = InstObjParams("mrs", "Mrs64", "RegMiscRegImmOp64",
3657741Sgblack@eecs.umich.edu                           mrsCode,
3664188Sgblack@eecs.umich.edu                           ["IsSerializeBefore"])
3674188Sgblack@eecs.umich.edu    header_output += RegMiscRegOp64Declare.subst(mrsIop)
3684188Sgblack@eecs.umich.edu    decoder_output += RegMiscRegOp64Constructor.subst(mrsIop)
3694188Sgblack@eecs.umich.edu    exec_output += BasicExecute.subst(mrsIop)
3704188Sgblack@eecs.umich.edu
3714188Sgblack@eecs.umich.edu    buildDataXRegInst("mrsNZCV", 1, '''
3724188Sgblack@eecs.umich.edu        CPSR cpsr = 0;
3734188Sgblack@eecs.umich.edu        cpsr.nz = CondCodesNZ;
3744188Sgblack@eecs.umich.edu        cpsr.c = CondCodesC;
3754188Sgblack@eecs.umich.edu        cpsr.v = CondCodesV;
3764188Sgblack@eecs.umich.edu        XDest = cpsr;
3774188Sgblack@eecs.umich.edu    ''')
3784188Sgblack@eecs.umich.edu
3794188Sgblack@eecs.umich.edu    msrCode = '''
3804188Sgblack@eecs.umich.edu        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
3814188Sgblack@eecs.umich.edu            flattenRegId(RegId(MiscRegClass, dest)).index();
3824188Sgblack@eecs.umich.edu        CPSR cpsr = Cpsr;
3834188Sgblack@eecs.umich.edu        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
3844188Sgblack@eecs.umich.edu        %s
3854188Sgblack@eecs.umich.edu        MiscDest_ud = XOp1;
3864188Sgblack@eecs.umich.edu    ''' % (msrMrs64EnabledCheckCode % ('Write', 'false'),)
3874188Sgblack@eecs.umich.edu
3884188Sgblack@eecs.umich.edu    msrIop = InstObjParams("msr", "Msr64", "MiscRegRegImmOp64",
3894188Sgblack@eecs.umich.edu                           msrCode,
3904188Sgblack@eecs.umich.edu                           ["IsSerializeAfter", "IsNonSpeculative"])
3914188Sgblack@eecs.umich.edu    header_output += MiscRegRegOp64Declare.subst(msrIop)
3924188Sgblack@eecs.umich.edu    decoder_output += MiscRegRegOp64Constructor.subst(msrIop)
3934188Sgblack@eecs.umich.edu    exec_output += BasicExecute.subst(msrIop)
3946075Sgblack@eecs.umich.edu
3956075Sgblack@eecs.umich.edu
3966075Sgblack@eecs.umich.edu    buildDataXRegInst("msrNZCV", 1, '''
3974188Sgblack@eecs.umich.edu        CPSR cpsr = XOp1;
3984188Sgblack@eecs.umich.edu        CondCodesNZ = cpsr.nz;
3994188Sgblack@eecs.umich.edu        CondCodesC = cpsr.c;
4004188Sgblack@eecs.umich.edu        CondCodesV = cpsr.v;
40113570Sbrandon.potter@amd.com    ''')
40213570Sbrandon.potter@amd.com
4034188Sgblack@eecs.umich.edu    msr_check_code = '''
4044188Sgblack@eecs.umich.edu        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
4054188Sgblack@eecs.umich.edu            flattenRegId(RegId(MiscRegClass, dest)).index();
4064188Sgblack@eecs.umich.edu        CPSR cpsr = Cpsr;
4074188Sgblack@eecs.umich.edu        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
4084188Sgblack@eecs.umich.edu        %s
4094188Sgblack@eecs.umich.edu    ''' % (msrMrs64EnabledCheckCode % ('Write', 'false'),)
4104188Sgblack@eecs.umich.edu
4114188Sgblack@eecs.umich.edu
4124188Sgblack@eecs.umich.edu    msrdczva_ea_code = msr_check_code
4134188Sgblack@eecs.umich.edu    msrdczva_ea_code += '''
4144188Sgblack@eecs.umich.edu           Request::Flags memAccessFlags = Request::CACHE_BLOCK_ZERO |
4155748SSteve.Reinhardt@amd.com               ArmISA::TLB::MustBeOne;
4164188Sgblack@eecs.umich.edu           EA = XBase;
4174188Sgblack@eecs.umich.edu           assert(!(Dczid & 0x10));
4184188Sgblack@eecs.umich.edu           uint64_t op_size = power(2, Dczid + 2);
4194188Sgblack@eecs.umich.edu           EA &= ~(op_size - 1);
4204188Sgblack@eecs.umich.edu
4214188Sgblack@eecs.umich.edu   '''
4224188Sgblack@eecs.umich.edu
4234188Sgblack@eecs.umich.edu    msrDCZVAIop = InstObjParams("dc zva", "Dczva", "SysDC64",
4244188Sgblack@eecs.umich.edu                                { "ea_code" : msrdczva_ea_code,
4254188Sgblack@eecs.umich.edu                                  "memacc_code" : ';',
4264188Sgblack@eecs.umich.edu                                  "use_uops" : 0,
4274188Sgblack@eecs.umich.edu                                  "op_wb" : ";",
4284188Sgblack@eecs.umich.edu                                  "fa_code" : ";"},
4294188Sgblack@eecs.umich.edu                                ['IsStore', 'IsMemRef']);
4304188Sgblack@eecs.umich.edu    header_output += DCStore64Declare.subst(msrDCZVAIop);
4314188Sgblack@eecs.umich.edu    decoder_output += DCStore64Constructor.subst(msrDCZVAIop);
4324188Sgblack@eecs.umich.edu    exec_output += DCStore64Execute.subst(msrDCZVAIop);
4334188Sgblack@eecs.umich.edu    exec_output += DCStore64InitiateAcc.subst(msrDCZVAIop);
4344188Sgblack@eecs.umich.edu    exec_output += Store64CompleteAcc.subst(msrDCZVAIop);
4354188Sgblack@eecs.umich.edu
4364188Sgblack@eecs.umich.edu
4374188Sgblack@eecs.umich.edu    msrdccvau_ea_code = msr_check_code
4384188Sgblack@eecs.umich.edu    msrdccvau_ea_code += '''
4394188Sgblack@eecs.umich.edu           Request::Flags memAccessFlags = Request::CLEAN | Request::DST_POU |
4404188Sgblack@eecs.umich.edu              ArmISA::TLB::MustBeOne;
4414264Sgblack@eecs.umich.edu           EA = XBase;
4424188Sgblack@eecs.umich.edu           System *sys = xc->tcBase()->getSystemPtr();
4434188Sgblack@eecs.umich.edu           Addr op_size = sys->cacheLineSize();
4444188Sgblack@eecs.umich.edu           EA &= ~(op_size - 1);
4454188Sgblack@eecs.umich.edu    '''
4464188Sgblack@eecs.umich.edu
4474188Sgblack@eecs.umich.edu    msrDCCVAUIop = InstObjParams("dc cvau", "Dccvau", "SysDC64",
4484188Sgblack@eecs.umich.edu                                 { "ea_code" : msrdccvau_ea_code,
4494188Sgblack@eecs.umich.edu                                   "memacc_code" : ';',
4504188Sgblack@eecs.umich.edu                                   "use_uops" : 0,
4514188Sgblack@eecs.umich.edu                                   "op_wb" : ";", "fa_code" : ";"},
4524188Sgblack@eecs.umich.edu                                 ['IsStore', 'IsMemRef']);
4534188Sgblack@eecs.umich.edu    header_output += DCStore64Declare.subst(msrDCCVAUIop);
4544188Sgblack@eecs.umich.edu    decoder_output += DCStore64Constructor.subst(msrDCCVAUIop);
4554188Sgblack@eecs.umich.edu    exec_output += DCStore64Execute.subst(msrDCCVAUIop);
4565513SMichael.Adler@intel.com    exec_output += DCStore64InitiateAcc.subst(msrDCCVAUIop);
4574188Sgblack@eecs.umich.edu    exec_output += Store64CompleteAcc.subst(msrDCCVAUIop);
4584188Sgblack@eecs.umich.edu
4594188Sgblack@eecs.umich.edu
4604188Sgblack@eecs.umich.edu    msrdccvac_ea_code = msr_check_code
4614188Sgblack@eecs.umich.edu    msrdccvac_ea_code += '''
4624188Sgblack@eecs.umich.edu           Request::Flags memAccessFlags = Request::CLEAN | Request::DST_POC |
4634188Sgblack@eecs.umich.edu              ArmISA::TLB::MustBeOne;
4644188Sgblack@eecs.umich.edu           EA = XBase;
4654188Sgblack@eecs.umich.edu           System *sys = xc->tcBase()->getSystemPtr();
4664188Sgblack@eecs.umich.edu           Addr op_size = sys->cacheLineSize();
4674188Sgblack@eecs.umich.edu           EA &= ~(op_size - 1);
4684188Sgblack@eecs.umich.edu    '''
4694188Sgblack@eecs.umich.edu
4704188Sgblack@eecs.umich.edu    msrDCCVACIop = InstObjParams("dc cvac", "Dccvac", "SysDC64",
4714188Sgblack@eecs.umich.edu                                 { "ea_code" : msrdccvac_ea_code,
4726109Ssanchezd@stanford.edu                                   "memacc_code" : ';',
4734188Sgblack@eecs.umich.edu                                   "use_uops" : 0,
4744188Sgblack@eecs.umich.edu                                   "op_wb" : ";", "fa_code" : ";"},
4754188Sgblack@eecs.umich.edu                                 ['IsStore', 'IsMemRef']);
4764188Sgblack@eecs.umich.edu    header_output += DCStore64Declare.subst(msrDCCVACIop);
4774188Sgblack@eecs.umich.edu    decoder_output += DCStore64Constructor.subst(msrDCCVACIop);
4784188Sgblack@eecs.umich.edu    exec_output += DCStore64Execute.subst(msrDCCVACIop);
4794188Sgblack@eecs.umich.edu    exec_output += DCStore64InitiateAcc.subst(msrDCCVACIop);
4804188Sgblack@eecs.umich.edu    exec_output += Store64CompleteAcc.subst(msrDCCVACIop);
4814188Sgblack@eecs.umich.edu
4824188Sgblack@eecs.umich.edu
4834188Sgblack@eecs.umich.edu    msrdccivac_ea_code = msr_check_code
4844188Sgblack@eecs.umich.edu    msrdccivac_ea_code += '''
4854188Sgblack@eecs.umich.edu           Request::Flags memAccessFlags = Request::CLEAN |
4864188Sgblack@eecs.umich.edu              Request::INVALIDATE | Request::DST_POC | ArmISA::TLB::MustBeOne;
4874188Sgblack@eecs.umich.edu           EA = XBase;
4884188Sgblack@eecs.umich.edu           System *sys = xc->tcBase()->getSystemPtr();
4894188Sgblack@eecs.umich.edu           Addr op_size = sys->cacheLineSize();
4904188Sgblack@eecs.umich.edu           EA &= ~(op_size - 1);
4914188Sgblack@eecs.umich.edu    '''
4924188Sgblack@eecs.umich.edu
4934188Sgblack@eecs.umich.edu    msrDCCIVACIop = InstObjParams("dc civac", "Dccivac", "SysDC64",
4944188Sgblack@eecs.umich.edu                                  { "ea_code" : msrdccivac_ea_code,
4954188Sgblack@eecs.umich.edu                                    "memacc_code" : ';',
4964188Sgblack@eecs.umich.edu                                    "use_uops" : 0,
4974188Sgblack@eecs.umich.edu                                    "op_wb" : ";", "fa_code" : ";"},
4984188Sgblack@eecs.umich.edu                                  ['IsStore', 'IsMemRef']);
4994188Sgblack@eecs.umich.edu    header_output += DCStore64Declare.subst(msrDCCIVACIop);
5004188Sgblack@eecs.umich.edu    decoder_output += DCStore64Constructor.subst(msrDCCIVACIop);
5016109Ssanchezd@stanford.edu    exec_output += DCStore64Execute.subst(msrDCCIVACIop);
5024188Sgblack@eecs.umich.edu    exec_output += DCStore64InitiateAcc.subst(msrDCCIVACIop);
5034188Sgblack@eecs.umich.edu    exec_output += Store64CompleteAcc.subst(msrDCCIVACIop);
5044188Sgblack@eecs.umich.edu
5054188Sgblack@eecs.umich.edu
5064188Sgblack@eecs.umich.edu    msrdcivac_ea_code = msr_check_code
5074188Sgblack@eecs.umich.edu    msrdcivac_ea_code += '''
5086109Ssanchezd@stanford.edu           Request::Flags memAccessFlags = Request::INVALIDATE |
5094188Sgblack@eecs.umich.edu              Request::DST_POC | ArmISA::TLB::MustBeOne;
5104188Sgblack@eecs.umich.edu           EA = XBase;
5114188Sgblack@eecs.umich.edu           HCR hcr = Hcr64;
5124188Sgblack@eecs.umich.edu           SCR scr = Scr64;
5134188Sgblack@eecs.umich.edu           if (el == EL1 && ArmSystem::haveVirtualization(xc->tcBase()) &&
5146109Ssanchezd@stanford.edu               hcr.vm && (scr.ns || !ArmSystem::haveSecurity(xc->tcBase()))) {
5154188Sgblack@eecs.umich.edu               memAccessFlags = memAccessFlags | Request::CLEAN;
5164188Sgblack@eecs.umich.edu           }
5174188Sgblack@eecs.umich.edu           System *sys = xc->tcBase()->getSystemPtr();
5184188Sgblack@eecs.umich.edu           Addr op_size = sys->cacheLineSize();
5194188Sgblack@eecs.umich.edu           EA &= ~(op_size - 1);
5204188Sgblack@eecs.umich.edu    '''
5214188Sgblack@eecs.umich.edu
5224188Sgblack@eecs.umich.edu    msrDCIVACIop = InstObjParams("dc ivac", "Dcivac", "SysDC64",
5234188Sgblack@eecs.umich.edu                                 { "ea_code" : msrdcivac_ea_code,
5244188Sgblack@eecs.umich.edu                                   "memacc_code" : ';',
5254188Sgblack@eecs.umich.edu                                   "use_uops" : 0,
5264236Sgblack@eecs.umich.edu                                   "op_wb" : ";", "fa_code" : ";"},
5274188Sgblack@eecs.umich.edu                                 ['IsStore', 'IsMemRef']);
5284188Sgblack@eecs.umich.edu    header_output += DCStore64Declare.subst(msrDCIVACIop);
5294188Sgblack@eecs.umich.edu    decoder_output += DCStore64Constructor.subst(msrDCIVACIop);
5304188Sgblack@eecs.umich.edu    exec_output += DCStore64Execute.subst(msrDCIVACIop);
5314188Sgblack@eecs.umich.edu    exec_output += DCStore64InitiateAcc.subst(msrDCIVACIop);
5324188Sgblack@eecs.umich.edu    exec_output += Store64CompleteAcc.subst(msrDCIVACIop);
5334188Sgblack@eecs.umich.edu
5345513SMichael.Adler@intel.com
5354188Sgblack@eecs.umich.edu    buildDataXImmInst("msrSP", '''
5364188Sgblack@eecs.umich.edu        if (!canWriteAArch64SysReg(
5374188Sgblack@eecs.umich.edu                (MiscRegIndex) xc->tcBase()->flattenRegId(
5384188Sgblack@eecs.umich.edu                   RegId(MiscRegClass, dest)).index(),
5394188Sgblack@eecs.umich.edu                Scr64, Cpsr, xc->tcBase())) {
5404188Sgblack@eecs.umich.edu            return std::make_shared<UndefinedInstruction>(machInst, false,
5414188Sgblack@eecs.umich.edu                                                          mnemonic);
5424188Sgblack@eecs.umich.edu        }
5434188Sgblack@eecs.umich.edu        MiscDest_ud = imm;
5444188Sgblack@eecs.umich.edu    ''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"])
5454188Sgblack@eecs.umich.edu
5464188Sgblack@eecs.umich.edu    buildDataXImmInst("msrDAIFSet", '''
5474188Sgblack@eecs.umich.edu        if (!canWriteAArch64SysReg(
5484188Sgblack@eecs.umich.edu                (MiscRegIndex) xc->tcBase()->flattenRegId(
5494188Sgblack@eecs.umich.edu                   RegId(MiscRegClass, dest)).index(),
5504188Sgblack@eecs.umich.edu                Scr64, Cpsr, xc->tcBase())) {
5514188Sgblack@eecs.umich.edu            return std::make_shared<UndefinedInstruction>(
55210495Snilay@cs.wisc.edu                            machInst, 0, EC_TRAPPED_MSR_MRS_64,
5534188Sgblack@eecs.umich.edu                            mnemonic);
5544188Sgblack@eecs.umich.edu        }
5554188Sgblack@eecs.umich.edu        CPSR cpsr = Cpsr;
5564188Sgblack@eecs.umich.edu        cpsr.daif = cpsr.daif | imm;
5574188Sgblack@eecs.umich.edu        Cpsr = cpsr;
5584188Sgblack@eecs.umich.edu    ''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"])
5594188Sgblack@eecs.umich.edu
5604188Sgblack@eecs.umich.edu    buildDataXImmInst("msrDAIFClr", '''
5614188Sgblack@eecs.umich.edu        if (!canWriteAArch64SysReg(
5624188Sgblack@eecs.umich.edu                (MiscRegIndex) xc->tcBase()->flattenRegId(
5634188Sgblack@eecs.umich.edu                   RegId(MiscRegClass, dest)).index(),
5644188Sgblack@eecs.umich.edu                Scr64, Cpsr, xc->tcBase())) {
5654188Sgblack@eecs.umich.edu            return std::make_shared<UndefinedInstruction>(
5664188Sgblack@eecs.umich.edu                                machInst, 0, EC_TRAPPED_MSR_MRS_64,
5674188Sgblack@eecs.umich.edu                                mnemonic);
5684188Sgblack@eecs.umich.edu        }
5694188Sgblack@eecs.umich.edu        CPSR cpsr = Cpsr;
5704188Sgblack@eecs.umich.edu        cpsr.daif = cpsr.daif & ~imm;
5714188Sgblack@eecs.umich.edu        Cpsr = cpsr;
57210495Snilay@cs.wisc.edu    ''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"])
5734188Sgblack@eecs.umich.edu
5744188Sgblack@eecs.umich.edu    def buildDataXCompInst(mnem, instType, suffix, code):
5754188Sgblack@eecs.umich.edu        global header_output, decoder_output, exec_output
5764188Sgblack@eecs.umich.edu        templateBase = "DataXCond%s" % instType
5774188Sgblack@eecs.umich.edu        iop = InstObjParams(mnem, mnem.capitalize() + suffix + "64",
5784188Sgblack@eecs.umich.edu                            templateBase + "Op", code)
5794188Sgblack@eecs.umich.edu        header_output += eval(templateBase + "Declare").subst(iop)
5804188Sgblack@eecs.umich.edu        decoder_output += eval(templateBase + "Constructor").subst(iop)
5814188Sgblack@eecs.umich.edu        exec_output += BasicExecute.subst(iop)
5824188Sgblack@eecs.umich.edu
5834188Sgblack@eecs.umich.edu    def buildDataXCondImmInst(mnem, code):
5844188Sgblack@eecs.umich.edu        buildDataXCompInst(mnem, "CompImm", "Imm", code)
5854188Sgblack@eecs.umich.edu    def buildDataXCondRegInst(mnem, code):
5866109Ssanchezd@stanford.edu        buildDataXCompInst(mnem, "CompReg", "Reg", code)
5874188Sgblack@eecs.umich.edu    def buildDataXCondSelInst(mnem, code):
5884188Sgblack@eecs.umich.edu        buildDataXCompInst(mnem, "Sel", "", code)
5894188Sgblack@eecs.umich.edu
5904188Sgblack@eecs.umich.edu    def condCompCode(flagType, op, imm):
5914188Sgblack@eecs.umich.edu        ccCode = createCcCode64(carryCode64[flagType], overflowCode64[flagType])
5924188Sgblack@eecs.umich.edu        opDecl = "uint64_t secOp M5_VAR_USED = imm;"
5934188Sgblack@eecs.umich.edu        if not imm:
5944188Sgblack@eecs.umich.edu            opDecl = "uint64_t secOp M5_VAR_USED = Op264;"
5954188Sgblack@eecs.umich.edu        return opDecl + '''
5964188Sgblack@eecs.umich.edu            if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) {
5974188Sgblack@eecs.umich.edu                uint64_t resTemp = Op164 ''' + op + ''' secOp;
5984188Sgblack@eecs.umich.edu        ''' + ccCode + '''
5994188Sgblack@eecs.umich.edu            } else {
6004188Sgblack@eecs.umich.edu                CondCodesNZ = (defCc >> 2) & 0x3;
6014188Sgblack@eecs.umich.edu                CondCodesC = (defCc >> 1) & 0x1;
6024188Sgblack@eecs.umich.edu                CondCodesV = defCc & 0x1;
6034188Sgblack@eecs.umich.edu            }
6044188Sgblack@eecs.umich.edu        '''
6054188Sgblack@eecs.umich.edu
6064188Sgblack@eecs.umich.edu    buildDataXCondImmInst("ccmn", condCompCode("add", "+", True))
6074188Sgblack@eecs.umich.edu    buildDataXCondImmInst("ccmp", condCompCode("sub", "-", True))
6084188Sgblack@eecs.umich.edu    buildDataXCondRegInst("ccmn", condCompCode("add", "+", False))
6094188Sgblack@eecs.umich.edu    buildDataXCondRegInst("ccmp", condCompCode("sub", "-", False))
6104188Sgblack@eecs.umich.edu
6114188Sgblack@eecs.umich.edu    condSelCode = '''
6126640Svince@csl.cornell.edu        if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) {
6134188Sgblack@eecs.umich.edu            Dest64 = Op164;
6144188Sgblack@eecs.umich.edu        } else {
61511886Sbrandon.potter@amd.com            Dest64 = %(altVal)s;
6164188Sgblack@eecs.umich.edu        }
6174188Sgblack@eecs.umich.edu    '''
6184188Sgblack@eecs.umich.edu    buildDataXCondSelInst("csel", condSelCode % {"altVal" : "Op264"})
6194188Sgblack@eecs.umich.edu    buildDataXCondSelInst("csinc", condSelCode % {"altVal" : "Op264 + 1"})
6204188Sgblack@eecs.umich.edu    buildDataXCondSelInst("csinv", condSelCode % {"altVal" : "~Op264"})
6214188Sgblack@eecs.umich.edu    buildDataXCondSelInst("csneg", condSelCode % {"altVal" : "-Op264"})
6224188Sgblack@eecs.umich.edu}};
6234188Sgblack@eecs.umich.edu