data64.isa revision 12505
110037SARM gem5 Developers// -*- mode:c++ -*-
210037SARM gem5 Developers
312505Snikos.nikoleris@arm.com// Copyright (c) 2011-2013, 2016-2018 ARM Limited
410037SARM gem5 Developers// All rights reserved
510037SARM gem5 Developers//
610037SARM gem5 Developers// The license below extends only to copyright in the software and shall
710037SARM gem5 Developers// not be construed as granting a license to any other intellectual
810037SARM gem5 Developers// property including but not limited to intellectual property relating
910037SARM gem5 Developers// to a hardware implementation of the functionality of the software
1010037SARM gem5 Developers// licensed hereunder.  You may use the software subject to the license
1110037SARM gem5 Developers// terms below provided that you ensure that this notice is replicated
1210037SARM gem5 Developers// unmodified and in its entirety in all distributions of the software,
1310037SARM gem5 Developers// modified or unmodified, in source code or in binary form.
1410037SARM gem5 Developers//
1510037SARM gem5 Developers// Redistribution and use in source and binary forms, with or without
1610037SARM gem5 Developers// modification, are permitted provided that the following conditions are
1710037SARM gem5 Developers// met: redistributions of source code must retain the above copyright
1810037SARM gem5 Developers// notice, this list of conditions and the following disclaimer;
1910037SARM gem5 Developers// redistributions in binary form must reproduce the above copyright
2010037SARM gem5 Developers// notice, this list of conditions and the following disclaimer in the
2110037SARM gem5 Developers// documentation and/or other materials provided with the distribution;
2210037SARM gem5 Developers// neither the name of the copyright holders nor the names of its
2310037SARM gem5 Developers// contributors may be used to endorse or promote products derived from
2410037SARM gem5 Developers// this software without specific prior written permission.
2510037SARM gem5 Developers//
2610037SARM gem5 Developers// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2710037SARM gem5 Developers// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2810037SARM gem5 Developers// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2910037SARM gem5 Developers// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3010037SARM gem5 Developers// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3110037SARM gem5 Developers// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3210037SARM gem5 Developers// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3310037SARM gem5 Developers// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3410037SARM gem5 Developers// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3510037SARM gem5 Developers// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3610037SARM gem5 Developers// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3710037SARM gem5 Developers//
3810037SARM gem5 Developers// Authors: Gabe Black
3910037SARM gem5 Developers
4010037SARM gem5 Developerslet {{
4110037SARM gem5 Developers
4210037SARM gem5 Developers    header_output = ""
4310037SARM gem5 Developers    decoder_output = ""
4410037SARM gem5 Developers    exec_output = ""
4510037SARM gem5 Developers
4610037SARM gem5 Developers    def createCcCode64(carry, overflow):
4710037SARM gem5 Developers        code = ""
4810037SARM gem5 Developers        code += '''
4910037SARM gem5 Developers            uint16_t _iz, _in;
5010037SARM gem5 Developers            _in = bits(resTemp, intWidth - 1);
5110037SARM gem5 Developers            _iz = ((resTemp & mask(intWidth)) == 0);
5210037SARM gem5 Developers            CondCodesNZ = (_in << 1) | _iz;
5311862Snikos.nikoleris@arm.com            DPRINTF(Arm, "(in, iz) = (%d, %d)\\n", _in, _iz);
5410037SARM gem5 Developers        '''
5510037SARM gem5 Developers        if overflow and overflow != "none":
5610037SARM gem5 Developers            code +=  '''
5710037SARM gem5 Developers                uint16_t _iv;
5810037SARM gem5 Developers                _iv = %s & 1;
5910037SARM gem5 Developers                CondCodesV = _iv;
6010037SARM gem5 Developers                DPRINTF(Arm, "(iv) = (%%d)\\n", _iv);
6110037SARM gem5 Developers            ''' % overflow
6210037SARM gem5 Developers        if carry and carry != "none":
6310037SARM gem5 Developers            code += '''
6410037SARM gem5 Developers                uint16_t _ic;
6510037SARM gem5 Developers                _ic = %s & 1;
6610037SARM gem5 Developers                CondCodesC = _ic;
6710037SARM gem5 Developers                DPRINTF(Arm, "(ic) = (%%d)\\n", _ic);
6810037SARM gem5 Developers            ''' % carry
6910037SARM gem5 Developers        return code
7010037SARM gem5 Developers
7110037SARM gem5 Developers    oldC = 'CondCodesC'
7210037SARM gem5 Developers    oldV = 'CondCodesV'
7310037SARM gem5 Developers    # Dicts of ways to set the carry flag.
7410037SARM gem5 Developers    carryCode64 = {
7510037SARM gem5 Developers        "none": "none",
7610037SARM gem5 Developers        "add": 'findCarry(intWidth, resTemp, Op164, secOp)',
7710037SARM gem5 Developers        "sub": 'findCarry(intWidth, resTemp, Op164, ~secOp)',
7810037SARM gem5 Developers        "logic": '0'
7910037SARM gem5 Developers    }
8010037SARM gem5 Developers    # Dict of ways to set the overflow flag.
8110037SARM gem5 Developers    overflowCode64 = {
8210037SARM gem5 Developers        "none": "none",
8310037SARM gem5 Developers        "add": 'findOverflow(intWidth, resTemp, Op164, secOp)',
8410037SARM gem5 Developers        "sub": 'findOverflow(intWidth, resTemp, Op164, ~secOp)',
8510037SARM gem5 Developers        "logic": '0'
8610037SARM gem5 Developers    }
8710037SARM gem5 Developers
8810037SARM gem5 Developers    immOp2 = "uint64_t secOp M5_VAR_USED = imm;"
8910037SARM gem5 Developers    sRegOp2 = "uint64_t secOp M5_VAR_USED = " + \
9010037SARM gem5 Developers              "shiftReg64(Op264, shiftAmt, shiftType, intWidth);"
9110037SARM gem5 Developers    eRegOp2 = "uint64_t secOp M5_VAR_USED = " + \
9210037SARM gem5 Developers              "extendReg64(Op264, extendType, shiftAmt, intWidth);"
9310037SARM gem5 Developers
9410037SARM gem5 Developers    def buildDataWork(mnem, code, flagType, suffix, buildCc, buildNonCc,
9510037SARM gem5 Developers                      base, templateBase):
9610037SARM gem5 Developers        code = '''
9710037SARM gem5 Developers        uint64_t resTemp M5_VAR_USED = 0;
9810037SARM gem5 Developers        ''' + code
9910037SARM gem5 Developers        ccCode = createCcCode64(carryCode64[flagType], overflowCode64[flagType])
10010037SARM gem5 Developers        Name = mnem.capitalize() + suffix
10110037SARM gem5 Developers        iop = InstObjParams(mnem, Name, base, code)
10210037SARM gem5 Developers        iopCc = InstObjParams(mnem + "s", Name + "Cc", base, code + ccCode)
10310037SARM gem5 Developers
10410037SARM gem5 Developers        def subst(iop):
10510037SARM gem5 Developers            global header_output, decoder_output, exec_output
10610037SARM gem5 Developers            header_output += eval(templateBase + "Declare").subst(iop)
10710037SARM gem5 Developers            decoder_output += eval(templateBase + "Constructor").subst(iop)
10810037SARM gem5 Developers            exec_output += BasicExecute.subst(iop)
10910037SARM gem5 Developers
11010037SARM gem5 Developers        if buildNonCc:
11110037SARM gem5 Developers            subst(iop)
11210037SARM gem5 Developers        if buildCc:
11310037SARM gem5 Developers            subst(iopCc)
11410037SARM gem5 Developers
11510037SARM gem5 Developers    def buildXImmDataInst(mnem, code, flagType = "logic", \
11610037SARM gem5 Developers                          buildCc = True, buildNonCc = True, \
11710037SARM gem5 Developers                          suffix = "XImm"):
11810037SARM gem5 Developers        buildDataWork(mnem, immOp2 + code, flagType, suffix,
11910037SARM gem5 Developers                      buildCc, buildNonCc, "DataXImmOp", "DataXImm")
12010037SARM gem5 Developers
12110037SARM gem5 Developers    def buildXSRegDataInst(mnem, code, flagType = "logic", \
12210037SARM gem5 Developers                           buildCc = True, buildNonCc = True, \
12310037SARM gem5 Developers                           suffix = "XSReg"):
12410037SARM gem5 Developers        buildDataWork(mnem, sRegOp2 + code, flagType, suffix,
12510037SARM gem5 Developers                      buildCc, buildNonCc, "DataXSRegOp", "DataXSReg")
12610037SARM gem5 Developers
12710037SARM gem5 Developers    def buildXERegDataInst(mnem, code, flagType = "logic", \
12810037SARM gem5 Developers                           buildCc = True, buildNonCc = True, \
12910037SARM gem5 Developers                           suffix = "XEReg"):
13010037SARM gem5 Developers        buildDataWork(mnem, eRegOp2 + code, flagType, suffix,
13110037SARM gem5 Developers                      buildCc, buildNonCc, "DataXERegOp", "DataXEReg")
13210037SARM gem5 Developers
13310037SARM gem5 Developers    def buildDataInst(mnem, code, flagType = "logic",
13410037SARM gem5 Developers                      buildCc = True, buildNonCc = True):
13510037SARM gem5 Developers        buildXImmDataInst(mnem, code, flagType, buildCc, buildNonCc)
13610037SARM gem5 Developers        buildXSRegDataInst(mnem, code, flagType, buildCc, buildNonCc)
13710037SARM gem5 Developers        buildXERegDataInst(mnem, code, flagType, buildCc, buildNonCc)
13810037SARM gem5 Developers
13910037SARM gem5 Developers    buildXImmDataInst("adr", "Dest64 = RawPC + imm", buildCc = False);
14010037SARM gem5 Developers    buildXImmDataInst("adrp", "Dest64 = (RawPC & ~mask(12)) + imm",
14110037SARM gem5 Developers                      buildCc = False);
14210037SARM gem5 Developers    buildDataInst("and", "Dest64 = resTemp = Op164 & secOp;")
14310037SARM gem5 Developers    buildDataInst("eor", "Dest64 = Op164 ^ secOp;", buildCc = False)
14410037SARM gem5 Developers    buildXSRegDataInst("eon", "Dest64 = Op164 ^ ~secOp;", buildCc = False)
14510037SARM gem5 Developers    buildDataInst("sub", "Dest64 = resTemp = Op164 - secOp;", "sub")
14610037SARM gem5 Developers    buildDataInst("add", "Dest64 = resTemp = Op164 + secOp;", "add")
14710037SARM gem5 Developers    buildXSRegDataInst("adc",
14810037SARM gem5 Developers            "Dest64 = resTemp = Op164 + secOp + %s;" % oldC, "add")
14910037SARM gem5 Developers    buildXSRegDataInst("sbc",
15010037SARM gem5 Developers            "Dest64 = resTemp = Op164 - secOp - !%s;" % oldC, "sub")
15110037SARM gem5 Developers    buildDataInst("orr", "Dest64 = Op164 | secOp;", buildCc = False)
15210037SARM gem5 Developers    buildXSRegDataInst("orn", "Dest64 = Op164 | ~secOp;", buildCc = False)
15310037SARM gem5 Developers    buildXSRegDataInst("bic", "Dest64 = resTemp = Op164 & ~secOp;")
15410037SARM gem5 Developers
15510037SARM gem5 Developers    def buildDataXImmInst(mnem, code, optArgs = []):
15610037SARM gem5 Developers        global header_output, decoder_output, exec_output
15710037SARM gem5 Developers        classNamePrefix = mnem[0].upper() + mnem[1:]
15810037SARM gem5 Developers        templateBase = "DataXImm"
15910037SARM gem5 Developers        iop = InstObjParams(mnem, classNamePrefix + "64",
16010037SARM gem5 Developers                            templateBase + "Op", code, optArgs)
16110037SARM gem5 Developers        header_output += eval(templateBase + "Declare").subst(iop)
16210037SARM gem5 Developers        decoder_output += eval(templateBase + "Constructor").subst(iop)
16310037SARM gem5 Developers        exec_output += BasicExecute.subst(iop)
16410037SARM gem5 Developers
16510037SARM gem5 Developers    def buildDataXRegInst(mnem, regOps, code, optArgs = [],
16610037SARM gem5 Developers                          overrideOpClass=None):
16710037SARM gem5 Developers        global header_output, decoder_output, exec_output
16810037SARM gem5 Developers        templateBase = "DataX%dReg" % regOps
16910037SARM gem5 Developers        classNamePrefix = mnem[0].upper() + mnem[1:]
17010037SARM gem5 Developers        if overrideOpClass:
17110037SARM gem5 Developers            iop = InstObjParams(mnem, classNamePrefix + "64",
17210037SARM gem5 Developers                                templateBase + "Op",
17310037SARM gem5 Developers                                { 'code': code, 'op_class': overrideOpClass},
17410037SARM gem5 Developers                                optArgs)
17510037SARM gem5 Developers        else:
17610037SARM gem5 Developers            iop = InstObjParams(mnem, classNamePrefix + "64",
17710037SARM gem5 Developers                                templateBase + "Op", code, optArgs)
17810037SARM gem5 Developers        header_output += eval(templateBase + "Declare").subst(iop)
17910037SARM gem5 Developers        decoder_output += eval(templateBase + "Constructor").subst(iop)
18010037SARM gem5 Developers        exec_output += BasicExecute.subst(iop)
18110037SARM gem5 Developers
18210037SARM gem5 Developers    buildDataXRegInst("madd", 3, "Dest64 = Op164 + Op264 * Op364",
18310037SARM gem5 Developers        overrideOpClass="IntMultOp")
18410037SARM gem5 Developers    buildDataXRegInst("msub", 3, "Dest64 = Op164 - Op264 * Op364",
18510037SARM gem5 Developers        overrideOpClass="IntMultOp")
18610037SARM gem5 Developers    buildDataXRegInst("smaddl", 3,
18710037SARM gem5 Developers        "XDest = XOp1 + sext<32>(WOp2) * sext<32>(WOp3)",
18810037SARM gem5 Developers        overrideOpClass="IntMultOp")
18910037SARM gem5 Developers    buildDataXRegInst("smsubl", 3,
19010037SARM gem5 Developers        "XDest = XOp1 - sext<32>(WOp2) * sext<32>(WOp3)",
19110037SARM gem5 Developers        overrideOpClass="IntMultOp")
19210037SARM gem5 Developers    buildDataXRegInst("smulh", 2, '''
19310037SARM gem5 Developers        uint64_t op1H = (int32_t)(XOp1 >> 32);
19410037SARM gem5 Developers        uint64_t op1L = (uint32_t)XOp1;
19510037SARM gem5 Developers        uint64_t op2H = (int32_t)(XOp2 >> 32);
19610037SARM gem5 Developers        uint64_t op2L = (uint32_t)XOp2;
19710037SARM gem5 Developers        uint64_t mid1 = ((op1L * op2L) >> 32) + op1H * op2L;
19810037SARM gem5 Developers        uint64_t mid2 = op1L * op2H;
19910037SARM gem5 Developers        uint64_t result = ((uint64_t)(uint32_t)mid1 + (uint32_t)mid2) >> 32;
20010037SARM gem5 Developers        result += shiftReg64(mid1, 32, ASR, intWidth);
20110037SARM gem5 Developers        result += shiftReg64(mid2, 32, ASR, intWidth);
20210037SARM gem5 Developers        XDest = result + op1H * op2H;
20310037SARM gem5 Developers    ''', overrideOpClass="IntMultOp")
20410037SARM gem5 Developers    buildDataXRegInst("umaddl", 3, "XDest = XOp1 + WOp2 * WOp3",
20510037SARM gem5 Developers        overrideOpClass="IntMultOp")
20610037SARM gem5 Developers    buildDataXRegInst("umsubl", 3, "XDest = XOp1 - WOp2 * WOp3",
20710037SARM gem5 Developers        overrideOpClass="IntMultOp")
20810037SARM gem5 Developers    buildDataXRegInst("umulh", 2, '''
20910037SARM gem5 Developers        uint64_t op1H = (uint32_t)(XOp1 >> 32);
21010037SARM gem5 Developers        uint64_t op1L = (uint32_t)XOp1;
21110037SARM gem5 Developers        uint64_t op2H = (uint32_t)(XOp2 >> 32);
21210037SARM gem5 Developers        uint64_t op2L = (uint32_t)XOp2;
21310037SARM gem5 Developers        uint64_t mid1 = ((op1L * op2L) >> 32) + op1H * op2L;
21410037SARM gem5 Developers        uint64_t mid2 = op1L * op2H;
21510037SARM gem5 Developers        uint64_t result = ((uint64_t)(uint32_t)mid1 + (uint32_t)mid2) >> 32;
21610037SARM gem5 Developers        result += mid1 >> 32;
21710037SARM gem5 Developers        result += mid2 >> 32;
21810037SARM gem5 Developers        XDest = result + op1H * op2H;
21910037SARM gem5 Developers    ''', overrideOpClass="IntMultOp")
22010037SARM gem5 Developers
22110037SARM gem5 Developers    buildDataXRegInst("asrv", 2,
22210037SARM gem5 Developers        "Dest64 = shiftReg64(Op164, Op264, ASR, intWidth)")
22310037SARM gem5 Developers    buildDataXRegInst("lslv", 2,
22410037SARM gem5 Developers        "Dest64 = shiftReg64(Op164, Op264, LSL, intWidth)")
22510037SARM gem5 Developers    buildDataXRegInst("lsrv", 2,
22610037SARM gem5 Developers        "Dest64 = shiftReg64(Op164, Op264, LSR, intWidth)")
22710037SARM gem5 Developers    buildDataXRegInst("rorv", 2,
22810037SARM gem5 Developers        "Dest64 = shiftReg64(Op164, Op264, ROR, intWidth)")
22912258Sgiacomo.travaglini@arm.com
23012258Sgiacomo.travaglini@arm.com    crcCode = '''
23112258Sgiacomo.travaglini@arm.com    constexpr uint8_t size_bytes = %(sz)d;
23212258Sgiacomo.travaglini@arm.com    constexpr uint32_t poly = %(polynom)s;
23312258Sgiacomo.travaglini@arm.com
23412258Sgiacomo.travaglini@arm.com    // Initial value is often a previously evaluated
23512258Sgiacomo.travaglini@arm.com    // crc value hence is always 32bit in CRC32
23612258Sgiacomo.travaglini@arm.com    uint32_t initial_crc = Op164 & 0xFFFFFFFF;
23712258Sgiacomo.travaglini@arm.com
23812258Sgiacomo.travaglini@arm.com    uint64_t data = htole(Op264);
23912258Sgiacomo.travaglini@arm.com    auto data_buffer = reinterpret_cast<uint8_t*>(&data);
24012258Sgiacomo.travaglini@arm.com
24112258Sgiacomo.travaglini@arm.com    Dest = crc32<poly>(
24212258Sgiacomo.travaglini@arm.com        data_buffer,   /* Message register */
24312258Sgiacomo.travaglini@arm.com        initial_crc,   /* Initial value of the CRC */
24412258Sgiacomo.travaglini@arm.com        size_bytes     /* Size of the original Message */
24512258Sgiacomo.travaglini@arm.com    );
24612258Sgiacomo.travaglini@arm.com    '''
24712258Sgiacomo.travaglini@arm.com    buildDataXRegInst("crc32b", 2,
24812258Sgiacomo.travaglini@arm.com        crcCode % {"sz": 1, "polynom": "0x04C11DB7"})
24912258Sgiacomo.travaglini@arm.com    buildDataXRegInst("crc32h", 2,
25012258Sgiacomo.travaglini@arm.com        crcCode % {"sz": 2, "polynom": "0x04C11DB7"})
25112258Sgiacomo.travaglini@arm.com    buildDataXRegInst("crc32w", 2,
25212258Sgiacomo.travaglini@arm.com        crcCode % {"sz": 4, "polynom": "0x04C11DB7"})
25312258Sgiacomo.travaglini@arm.com    buildDataXRegInst("crc32x", 2,
25412258Sgiacomo.travaglini@arm.com        crcCode % {"sz": 8, "polynom": "0x04C11DB7"})
25512258Sgiacomo.travaglini@arm.com
25612258Sgiacomo.travaglini@arm.com    buildDataXRegInst("crc32cb", 2,
25712258Sgiacomo.travaglini@arm.com        crcCode % {"sz": 1, "polynom": "0x1EDC6F41"})
25812258Sgiacomo.travaglini@arm.com    buildDataXRegInst("crc32ch", 2,
25912258Sgiacomo.travaglini@arm.com        crcCode % {"sz": 2, "polynom": "0x1EDC6F41"})
26012258Sgiacomo.travaglini@arm.com    buildDataXRegInst("crc32cw", 2,
26112258Sgiacomo.travaglini@arm.com        crcCode % {"sz": 4, "polynom": "0x1EDC6F41"})
26212258Sgiacomo.travaglini@arm.com    buildDataXRegInst("crc32cx", 2,
26312258Sgiacomo.travaglini@arm.com        crcCode % {"sz": 8, "polynom": "0x1EDC6F41"})
26412258Sgiacomo.travaglini@arm.com
26510037SARM gem5 Developers    buildDataXRegInst("sdiv", 2, '''
26610037SARM gem5 Developers        int64_t op1 = Op164;
26710037SARM gem5 Developers        int64_t op2 = Op264;
26810037SARM gem5 Developers        if (intWidth == 32) {
26910037SARM gem5 Developers            op1 = sext<32>(op1);
27010037SARM gem5 Developers            op2 = sext<32>(op2);
27110037SARM gem5 Developers        }
27210037SARM gem5 Developers        Dest64 = op2 == -1 ? -op1 : op2 ? op1 / op2 : 0;
27310037SARM gem5 Developers    ''', overrideOpClass="IntDivOp")
27410037SARM gem5 Developers    buildDataXRegInst("udiv", 2, "Dest64 = Op264 ? Op164 / Op264 : 0",
27510037SARM gem5 Developers        overrideOpClass="IntDivOp")
27610037SARM gem5 Developers
27710037SARM gem5 Developers    buildDataXRegInst("cls", 1, '''
27810037SARM gem5 Developers        uint64_t op1 = Op164;
27910037SARM gem5 Developers        if (bits(op1, intWidth - 1))
28010037SARM gem5 Developers            op1 ^= mask(intWidth);
28110037SARM gem5 Developers        Dest64 = (op1 == 0) ? intWidth - 1 : (intWidth - 2 - findMsbSet(op1));
28210037SARM gem5 Developers    ''')
28310037SARM gem5 Developers    buildDataXRegInst("clz", 1, '''
28410037SARM gem5 Developers        Dest64 = (Op164 == 0) ? intWidth : (intWidth - 1 - findMsbSet(Op164));
28510037SARM gem5 Developers    ''')
28610037SARM gem5 Developers    buildDataXRegInst("rbit", 1, '''
28712227Sgiacomo.travaglini@arm.com        Dest64 = reverseBits(Op164, intWidth/8);
28810037SARM gem5 Developers    ''')
28910037SARM gem5 Developers    buildDataXRegInst("rev", 1, '''
29010037SARM gem5 Developers        if (intWidth == 32)
29110037SARM gem5 Developers            Dest64 = betole<uint32_t>(Op164);
29210037SARM gem5 Developers        else
29310037SARM gem5 Developers            Dest64 = betole<uint64_t>(Op164);
29410037SARM gem5 Developers    ''')
29510037SARM gem5 Developers    buildDataXRegInst("rev16", 1, '''
29610037SARM gem5 Developers        int count = intWidth / 16;
29710037SARM gem5 Developers        uint64_t result = 0;
29810037SARM gem5 Developers        for (unsigned i = 0; i < count; i++) {
29910037SARM gem5 Developers            uint16_t hw = Op164 >> (i * 16);
30010037SARM gem5 Developers            result |= (uint64_t)betole<uint16_t>(hw) << (i * 16);
30110037SARM gem5 Developers        }
30210037SARM gem5 Developers        Dest64 = result;
30310037SARM gem5 Developers    ''')
30410037SARM gem5 Developers    buildDataXRegInst("rev32", 1, '''
30510037SARM gem5 Developers        int count = intWidth / 32;
30610037SARM gem5 Developers        uint64_t result = 0;
30710037SARM gem5 Developers        for (unsigned i = 0; i < count; i++) {
30810037SARM gem5 Developers            uint32_t hw = Op164 >> (i * 32);
30910037SARM gem5 Developers            result |= (uint64_t)betole<uint32_t>(hw) << (i * 32);
31010037SARM gem5 Developers        }
31110037SARM gem5 Developers        Dest64 = result;
31210037SARM gem5 Developers    ''')
31310037SARM gem5 Developers
31410037SARM gem5 Developers    msrMrs64EnabledCheckCode = '''
31510037SARM gem5 Developers        // Check for read/write access right
31610037SARM gem5 Developers        if (!can%sAArch64SysReg(flat_idx, Scr64, cpsr, xc->tcBase())) {
31710037SARM gem5 Developers            if (flat_idx == MISCREG_DAIF ||
31810037SARM gem5 Developers                flat_idx == MISCREG_DC_ZVA_Xt ||
31910037SARM gem5 Developers                flat_idx == MISCREG_DC_CVAC_Xt ||
32012359Snikos.nikoleris@arm.com                flat_idx == MISCREG_DC_CIVAC_Xt ||
32112359Snikos.nikoleris@arm.com                flat_idx == MISCREG_DC_IVAC_Xt
32210037SARM gem5 Developers                )
32310474Sandreas.hansson@arm.com                return std::make_shared<UndefinedInstruction>(
32410474Sandreas.hansson@arm.com                                    machInst, 0, EC_TRAPPED_MSR_MRS_64,
32510205SAli.Saidi@ARM.com                                    mnemonic);
32610474Sandreas.hansson@arm.com            return std::make_shared<UndefinedInstruction>(machInst, false,
32710474Sandreas.hansson@arm.com                                                          mnemonic);
32810037SARM gem5 Developers        }
32910037SARM gem5 Developers
33010037SARM gem5 Developers        // Check for traps to supervisor (FP/SIMD regs)
33110037SARM gem5 Developers        if (el <= EL1 && msrMrs64TrapToSup(flat_idx, el, Cpacr64))
33210474Sandreas.hansson@arm.com            return std::make_shared<SupervisorTrap>(machInst, 0x1E00000,
33310474Sandreas.hansson@arm.com                                                    EC_TRAPPED_SIMD_FP);
33410037SARM gem5 Developers
33510037SARM gem5 Developers        bool is_vfp_neon = false;
33610037SARM gem5 Developers
33710037SARM gem5 Developers        // Check for traps to hypervisor
33810037SARM gem5 Developers        if ((ArmSystem::haveVirtualization(xc->tcBase()) && el <= EL2) &&
33911582SDylan.Johnson@ARM.com            msrMrs64TrapToHyp(flat_idx, el, %s, CptrEl264, Hcr64, &is_vfp_neon)) {
34010474Sandreas.hansson@arm.com            return std::make_shared<HypervisorTrap>(
34110474Sandreas.hansson@arm.com                machInst, is_vfp_neon ? 0x1E00000 : imm,
34210037SARM gem5 Developers                is_vfp_neon ? EC_TRAPPED_SIMD_FP : EC_TRAPPED_MSR_MRS_64);
34310037SARM gem5 Developers        }
34410037SARM gem5 Developers
34510037SARM gem5 Developers        // Check for traps to secure monitor
34610037SARM gem5 Developers        if ((ArmSystem::haveSecurity(xc->tcBase()) && el <= EL3) &&
34710037SARM gem5 Developers            msrMrs64TrapToMon(flat_idx, CptrEl364, el, &is_vfp_neon)) {
34810474Sandreas.hansson@arm.com            return std::make_shared<SecureMonitorTrap>(
34910474Sandreas.hansson@arm.com                machInst,
35010037SARM gem5 Developers                is_vfp_neon ? 0x1E00000 : imm,
35110037SARM gem5 Developers                is_vfp_neon ? EC_TRAPPED_SIMD_FP : EC_TRAPPED_MSR_MRS_64);
35210037SARM gem5 Developers        }
35310037SARM gem5 Developers    '''
35410037SARM gem5 Developers
35512280Sgiacomo.travaglini@arm.com    mrsCode = '''
35610037SARM gem5 Developers        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
35712106SRekai.GonzalezAlberquilla@arm.com            flattenRegId(RegId(MiscRegClass, op1)).index();
35810037SARM gem5 Developers        CPSR cpsr = Cpsr;
35910037SARM gem5 Developers        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
36010037SARM gem5 Developers        %s
36110037SARM gem5 Developers        XDest = MiscOp1_ud;
36212280Sgiacomo.travaglini@arm.com    ''' % (msrMrs64EnabledCheckCode % ('Read', 'true'),)
36312280Sgiacomo.travaglini@arm.com
36412280Sgiacomo.travaglini@arm.com    mrsIop = InstObjParams("mrs", "Mrs64", "RegMiscRegImmOp64",
36512280Sgiacomo.travaglini@arm.com                           mrsCode,
36612280Sgiacomo.travaglini@arm.com                           ["IsSerializeBefore"])
36712280Sgiacomo.travaglini@arm.com    header_output += RegMiscRegOp64Declare.subst(mrsIop)
36812280Sgiacomo.travaglini@arm.com    decoder_output += RegMiscRegOp64Constructor.subst(mrsIop)
36912280Sgiacomo.travaglini@arm.com    exec_output += BasicExecute.subst(mrsIop)
37010037SARM gem5 Developers
37110037SARM gem5 Developers    buildDataXRegInst("mrsNZCV", 1, '''
37210037SARM gem5 Developers        CPSR cpsr = 0;
37310037SARM gem5 Developers        cpsr.nz = CondCodesNZ;
37410037SARM gem5 Developers        cpsr.c = CondCodesC;
37510037SARM gem5 Developers        cpsr.v = CondCodesV;
37610037SARM gem5 Developers        XDest = cpsr;
37710037SARM gem5 Developers    ''')
37810037SARM gem5 Developers
37912280Sgiacomo.travaglini@arm.com    msrCode = '''
38010037SARM gem5 Developers        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
38112106SRekai.GonzalezAlberquilla@arm.com            flattenRegId(RegId(MiscRegClass, dest)).index();
38210037SARM gem5 Developers        CPSR cpsr = Cpsr;
38310037SARM gem5 Developers        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
38410037SARM gem5 Developers        %s
38510037SARM gem5 Developers        MiscDest_ud = XOp1;
38612280Sgiacomo.travaglini@arm.com    ''' % (msrMrs64EnabledCheckCode % ('Write', 'false'),)
38712280Sgiacomo.travaglini@arm.com
38812280Sgiacomo.travaglini@arm.com    msrIop = InstObjParams("msr", "Msr64", "MiscRegRegImmOp64",
38912280Sgiacomo.travaglini@arm.com                           msrCode,
39012280Sgiacomo.travaglini@arm.com                           ["IsSerializeAfter", "IsNonSpeculative"])
39112280Sgiacomo.travaglini@arm.com    header_output += MiscRegRegOp64Declare.subst(msrIop)
39212280Sgiacomo.travaglini@arm.com    decoder_output += MiscRegRegOp64Constructor.subst(msrIop)
39312280Sgiacomo.travaglini@arm.com    exec_output += BasicExecute.subst(msrIop)
39412280Sgiacomo.travaglini@arm.com
39510037SARM gem5 Developers
39610037SARM gem5 Developers    buildDataXRegInst("msrNZCV", 1, '''
39710037SARM gem5 Developers        CPSR cpsr = XOp1;
39810037SARM gem5 Developers        CondCodesNZ = cpsr.nz;
39910037SARM gem5 Developers        CondCodesC = cpsr.c;
40010037SARM gem5 Developers        CondCodesV = cpsr.v;
40110037SARM gem5 Developers    ''')
40210037SARM gem5 Developers
40310037SARM gem5 Developers    msrdczva_ea_code = '''
40412106SRekai.GonzalezAlberquilla@arm.com        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId(
40512106SRekai.GonzalezAlberquilla@arm.com                                   RegId(MiscRegClass, dest)).index();
40610037SARM gem5 Developers        CPSR cpsr = Cpsr;
40710037SARM gem5 Developers        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
40810037SARM gem5 Developers    '''
40910037SARM gem5 Developers
41010037SARM gem5 Developers    msrdczva_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false')
41110037SARM gem5 Developers    msrdczva_ea_code += '''
41210037SARM gem5 Developers           Request::Flags memAccessFlags = Request::CACHE_BLOCK_ZERO|ArmISA::TLB::MustBeOne;
41310037SARM gem5 Developers           EA = XBase;
41410037SARM gem5 Developers           assert(!(Dczid & 0x10));
41510037SARM gem5 Developers           uint64_t op_size = power(2, Dczid + 2);
41610037SARM gem5 Developers           EA &= ~(op_size - 1);
41710037SARM gem5 Developers
41810037SARM gem5 Developers   '''
41910037SARM gem5 Developers
42012504Snikos.nikoleris@arm.com    msrDCZVAIop = InstObjParams("dc zva", "Dczva", "SysDC64",
42110037SARM gem5 Developers                { "ea_code" : msrdczva_ea_code,
42210037SARM gem5 Developers                  "memacc_code" : ";", "use_uops" : 0,
42310037SARM gem5 Developers                  "op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']);
42410037SARM gem5 Developers    header_output += DCStore64Declare.subst(msrDCZVAIop);
42510037SARM gem5 Developers    decoder_output += DCStore64Constructor.subst(msrDCZVAIop);
42610037SARM gem5 Developers    exec_output += DCStore64Execute.subst(msrDCZVAIop);
42710037SARM gem5 Developers    exec_output += DCStore64InitiateAcc.subst(msrDCZVAIop);
42810037SARM gem5 Developers    exec_output += Store64CompleteAcc.subst(msrDCZVAIop);
42910037SARM gem5 Developers
43010037SARM gem5 Developers
43112359Snikos.nikoleris@arm.com    msrdccvau_ea_code = '''
43212359Snikos.nikoleris@arm.com        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId(
43312359Snikos.nikoleris@arm.com                                   RegId(MiscRegClass, dest)).index();
43412359Snikos.nikoleris@arm.com        CPSR cpsr = Cpsr;
43512359Snikos.nikoleris@arm.com        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
43612359Snikos.nikoleris@arm.com    '''
43712359Snikos.nikoleris@arm.com
43812359Snikos.nikoleris@arm.com    msrdccvau_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false')
43912359Snikos.nikoleris@arm.com    msrdccvau_ea_code += '''
44012359Snikos.nikoleris@arm.com           Request::Flags memAccessFlags = Request::CLEAN | Request::DST_POU |
44112359Snikos.nikoleris@arm.com              ArmISA::TLB::MustBeOne;
44212359Snikos.nikoleris@arm.com           EA = XBase;
44312359Snikos.nikoleris@arm.com           System *sys = xc->tcBase()->getSystemPtr();
44412359Snikos.nikoleris@arm.com           Addr op_size = sys->cacheLineSize();
44512359Snikos.nikoleris@arm.com           EA &= ~(op_size - 1);
44612359Snikos.nikoleris@arm.com    '''
44712359Snikos.nikoleris@arm.com
44812359Snikos.nikoleris@arm.com    msrDCCVAUIop = InstObjParams("dc cvau", "Dccvau", "SysDC64",
44912359Snikos.nikoleris@arm.com                { "ea_code" : msrdccvau_ea_code,
45012359Snikos.nikoleris@arm.com                  "memacc_code" : ";", "use_uops" : 0,
45112359Snikos.nikoleris@arm.com                  "op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']);
45212359Snikos.nikoleris@arm.com    header_output += DCStore64Declare.subst(msrDCCVAUIop);
45312359Snikos.nikoleris@arm.com    decoder_output += DCStore64Constructor.subst(msrDCCVAUIop);
45412359Snikos.nikoleris@arm.com    exec_output += DCStore64Execute.subst(msrDCCVAUIop);
45512359Snikos.nikoleris@arm.com    exec_output += DCStore64InitiateAcc.subst(msrDCCVAUIop);
45612359Snikos.nikoleris@arm.com    exec_output += Store64CompleteAcc.subst(msrDCCVAUIop);
45712359Snikos.nikoleris@arm.com
45812359Snikos.nikoleris@arm.com
45912359Snikos.nikoleris@arm.com    msrdccvac_ea_code = '''
46012359Snikos.nikoleris@arm.com        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId(
46112359Snikos.nikoleris@arm.com            RegId(MiscRegClass, dest)).index();
46212359Snikos.nikoleris@arm.com        CPSR cpsr = Cpsr;
46312359Snikos.nikoleris@arm.com        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
46412359Snikos.nikoleris@arm.com    '''
46512359Snikos.nikoleris@arm.com
46612359Snikos.nikoleris@arm.com    msrdccvac_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false')
46712359Snikos.nikoleris@arm.com    msrdccvac_ea_code += '''
46812359Snikos.nikoleris@arm.com           Request::Flags memAccessFlags = Request::CLEAN | Request::DST_POC |
46912359Snikos.nikoleris@arm.com              ArmISA::TLB::MustBeOne;
47012359Snikos.nikoleris@arm.com           EA = XBase;
47112359Snikos.nikoleris@arm.com           System *sys = xc->tcBase()->getSystemPtr();
47212359Snikos.nikoleris@arm.com           Addr op_size = sys->cacheLineSize();
47312359Snikos.nikoleris@arm.com           EA &= ~(op_size - 1);
47412359Snikos.nikoleris@arm.com    '''
47512359Snikos.nikoleris@arm.com
47612359Snikos.nikoleris@arm.com    msrDCCVACIop = InstObjParams("dc cvac", "Dccvac", "SysDC64",
47712359Snikos.nikoleris@arm.com                { "ea_code" : msrdccvac_ea_code,
47812359Snikos.nikoleris@arm.com                  "memacc_code" : ";", "use_uops" : 0,
47912359Snikos.nikoleris@arm.com                  "op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']);
48012359Snikos.nikoleris@arm.com    header_output += DCStore64Declare.subst(msrDCCVACIop);
48112359Snikos.nikoleris@arm.com    decoder_output += DCStore64Constructor.subst(msrDCCVACIop);
48212359Snikos.nikoleris@arm.com    exec_output += DCStore64Execute.subst(msrDCCVACIop);
48312359Snikos.nikoleris@arm.com    exec_output += DCStore64InitiateAcc.subst(msrDCCVACIop);
48412359Snikos.nikoleris@arm.com    exec_output += Store64CompleteAcc.subst(msrDCCVACIop);
48512359Snikos.nikoleris@arm.com
48612359Snikos.nikoleris@arm.com
48712359Snikos.nikoleris@arm.com    msrdccivac_ea_code = '''
48812359Snikos.nikoleris@arm.com        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId(
48912359Snikos.nikoleris@arm.com                                   RegId(MiscRegClass, dest)).index();
49012359Snikos.nikoleris@arm.com        CPSR cpsr = Cpsr;
49112359Snikos.nikoleris@arm.com        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
49212359Snikos.nikoleris@arm.com    '''
49312359Snikos.nikoleris@arm.com
49412359Snikos.nikoleris@arm.com    msrdccivac_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false')
49512359Snikos.nikoleris@arm.com    msrdccivac_ea_code += '''
49612359Snikos.nikoleris@arm.com           Request::Flags memAccessFlags = Request::CLEAN |
49712359Snikos.nikoleris@arm.com              Request::INVALIDATE | Request::DST_POC | ArmISA::TLB::MustBeOne;
49812359Snikos.nikoleris@arm.com           EA = XBase;
49912359Snikos.nikoleris@arm.com           System *sys = xc->tcBase()->getSystemPtr();
50012359Snikos.nikoleris@arm.com           Addr op_size = sys->cacheLineSize();
50112359Snikos.nikoleris@arm.com           EA &= ~(op_size - 1);
50212359Snikos.nikoleris@arm.com    '''
50312359Snikos.nikoleris@arm.com
50412359Snikos.nikoleris@arm.com    msrDCCIVACIop = InstObjParams("dc civac", "Dccivac", "SysDC64",
50512359Snikos.nikoleris@arm.com                { "ea_code" : msrdccivac_ea_code,
50612359Snikos.nikoleris@arm.com                  "memacc_code" : ";", "use_uops" : 0,
50712359Snikos.nikoleris@arm.com                  "op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']);
50812359Snikos.nikoleris@arm.com    header_output += DCStore64Declare.subst(msrDCCIVACIop);
50912359Snikos.nikoleris@arm.com    decoder_output += DCStore64Constructor.subst(msrDCCIVACIop);
51012359Snikos.nikoleris@arm.com    exec_output += DCStore64Execute.subst(msrDCCIVACIop);
51112359Snikos.nikoleris@arm.com    exec_output += DCStore64InitiateAcc.subst(msrDCCIVACIop);
51212359Snikos.nikoleris@arm.com    exec_output += Store64CompleteAcc.subst(msrDCCIVACIop);
51312359Snikos.nikoleris@arm.com
51412359Snikos.nikoleris@arm.com
51512359Snikos.nikoleris@arm.com    msrdcivac_ea_code = '''
51612359Snikos.nikoleris@arm.com        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId(
51712359Snikos.nikoleris@arm.com                                   RegId(MiscRegClass, dest)).index();
51812359Snikos.nikoleris@arm.com        CPSR cpsr = Cpsr;
51912359Snikos.nikoleris@arm.com        ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
52012359Snikos.nikoleris@arm.com    '''
52112359Snikos.nikoleris@arm.com
52212359Snikos.nikoleris@arm.com    msrdcivac_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false')
52312359Snikos.nikoleris@arm.com    msrdcivac_ea_code += '''
52412359Snikos.nikoleris@arm.com           Request::Flags memAccessFlags = Request::INVALIDATE |
52512359Snikos.nikoleris@arm.com              Request::DST_POC | ArmISA::TLB::MustBeOne;
52612359Snikos.nikoleris@arm.com           EA = XBase;
52712505Snikos.nikoleris@arm.com           HCR hcr = Hcr64;
52812505Snikos.nikoleris@arm.com           SCR scr = Scr64;
52912505Snikos.nikoleris@arm.com           if (el == EL1 && ArmSystem::haveVirtualization(xc->tcBase()) &&
53012505Snikos.nikoleris@arm.com               hcr.vm && (scr.ns || !ArmSystem::haveSecurity(xc->tcBase()))) {
53112505Snikos.nikoleris@arm.com               memAccessFlags = memAccessFlags | Request::CLEAN;
53212505Snikos.nikoleris@arm.com           }
53312359Snikos.nikoleris@arm.com           System *sys = xc->tcBase()->getSystemPtr();
53412359Snikos.nikoleris@arm.com           Addr op_size = sys->cacheLineSize();
53512359Snikos.nikoleris@arm.com           EA &= ~(op_size - 1);
53612359Snikos.nikoleris@arm.com    '''
53712359Snikos.nikoleris@arm.com
53812359Snikos.nikoleris@arm.com    msrDCIVACIop = InstObjParams("dc ivac", "Dcivac", "SysDC64",
53912359Snikos.nikoleris@arm.com                { "ea_code" : msrdcivac_ea_code,
54012359Snikos.nikoleris@arm.com                  "memacc_code" : ";", "use_uops" : 0,
54112359Snikos.nikoleris@arm.com                  "op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']);
54212359Snikos.nikoleris@arm.com    header_output += DCStore64Declare.subst(msrDCIVACIop);
54312359Snikos.nikoleris@arm.com    decoder_output += DCStore64Constructor.subst(msrDCIVACIop);
54412359Snikos.nikoleris@arm.com    exec_output += DCStore64Execute.subst(msrDCIVACIop);
54512359Snikos.nikoleris@arm.com    exec_output += DCStore64InitiateAcc.subst(msrDCIVACIop);
54612359Snikos.nikoleris@arm.com    exec_output += Store64CompleteAcc.subst(msrDCIVACIop);
54712359Snikos.nikoleris@arm.com
54810037SARM gem5 Developers
54910037SARM gem5 Developers    buildDataXImmInst("msrSP", '''
55010037SARM gem5 Developers        if (!canWriteAArch64SysReg(
55112106SRekai.GonzalezAlberquilla@arm.com                (MiscRegIndex) xc->tcBase()->flattenRegId(
55212106SRekai.GonzalezAlberquilla@arm.com                   RegId(MiscRegClass, dest)).index(),
55310037SARM gem5 Developers                Scr64, Cpsr, xc->tcBase())) {
55410474Sandreas.hansson@arm.com            return std::make_shared<UndefinedInstruction>(machInst, false,
55510474Sandreas.hansson@arm.com                                                          mnemonic);
55610037SARM gem5 Developers        }
55710037SARM gem5 Developers        MiscDest_ud = imm;
55810037SARM gem5 Developers    ''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"])
55910037SARM gem5 Developers
56010037SARM gem5 Developers    buildDataXImmInst("msrDAIFSet", '''
56110037SARM gem5 Developers        if (!canWriteAArch64SysReg(
56212106SRekai.GonzalezAlberquilla@arm.com                (MiscRegIndex) xc->tcBase()->flattenRegId(
56312106SRekai.GonzalezAlberquilla@arm.com                   RegId(MiscRegClass, dest)).index(),
56410037SARM gem5 Developers                Scr64, Cpsr, xc->tcBase())) {
56510474Sandreas.hansson@arm.com            return std::make_shared<UndefinedInstruction>(
56610474Sandreas.hansson@arm.com                            machInst, 0, EC_TRAPPED_MSR_MRS_64,
56710205SAli.Saidi@ARM.com                            mnemonic);
56810037SARM gem5 Developers        }
56910037SARM gem5 Developers        CPSR cpsr = Cpsr;
57010037SARM gem5 Developers        cpsr.daif = cpsr.daif | imm;
57110037SARM gem5 Developers        Cpsr = cpsr;
57210037SARM gem5 Developers    ''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"])
57310037SARM gem5 Developers
57410037SARM gem5 Developers    buildDataXImmInst("msrDAIFClr", '''
57510037SARM gem5 Developers        if (!canWriteAArch64SysReg(
57612106SRekai.GonzalezAlberquilla@arm.com                (MiscRegIndex) xc->tcBase()->flattenRegId(
57712106SRekai.GonzalezAlberquilla@arm.com                   RegId(MiscRegClass, dest)).index(),
57810037SARM gem5 Developers                Scr64, Cpsr, xc->tcBase())) {
57910474Sandreas.hansson@arm.com            return std::make_shared<UndefinedInstruction>(
58010474Sandreas.hansson@arm.com                                machInst, 0, EC_TRAPPED_MSR_MRS_64,
58110205SAli.Saidi@ARM.com                                mnemonic);
58210037SARM gem5 Developers        }
58310037SARM gem5 Developers        CPSR cpsr = Cpsr;
58410037SARM gem5 Developers        cpsr.daif = cpsr.daif & ~imm;
58510037SARM gem5 Developers        Cpsr = cpsr;
58610037SARM gem5 Developers    ''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"])
58710037SARM gem5 Developers
58810037SARM gem5 Developers    def buildDataXCompInst(mnem, instType, suffix, code):
58910037SARM gem5 Developers        global header_output, decoder_output, exec_output
59010037SARM gem5 Developers        templateBase = "DataXCond%s" % instType
59110037SARM gem5 Developers        iop = InstObjParams(mnem, mnem.capitalize() + suffix + "64",
59210037SARM gem5 Developers                            templateBase + "Op", code)
59310037SARM gem5 Developers        header_output += eval(templateBase + "Declare").subst(iop)
59410037SARM gem5 Developers        decoder_output += eval(templateBase + "Constructor").subst(iop)
59510037SARM gem5 Developers        exec_output += BasicExecute.subst(iop)
59610037SARM gem5 Developers
59710037SARM gem5 Developers    def buildDataXCondImmInst(mnem, code):
59810037SARM gem5 Developers        buildDataXCompInst(mnem, "CompImm", "Imm", code)
59910037SARM gem5 Developers    def buildDataXCondRegInst(mnem, code):
60010037SARM gem5 Developers        buildDataXCompInst(mnem, "CompReg", "Reg", code)
60110037SARM gem5 Developers    def buildDataXCondSelInst(mnem, code):
60210037SARM gem5 Developers        buildDataXCompInst(mnem, "Sel", "", code)
60310037SARM gem5 Developers
60410037SARM gem5 Developers    def condCompCode(flagType, op, imm):
60510037SARM gem5 Developers        ccCode = createCcCode64(carryCode64[flagType], overflowCode64[flagType])
60610037SARM gem5 Developers        opDecl = "uint64_t secOp M5_VAR_USED = imm;"
60710037SARM gem5 Developers        if not imm:
60810037SARM gem5 Developers            opDecl = "uint64_t secOp M5_VAR_USED = Op264;"
60910037SARM gem5 Developers        return opDecl + '''
61010037SARM gem5 Developers            if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) {
61110037SARM gem5 Developers                uint64_t resTemp = Op164 ''' + op + ''' secOp;
61210037SARM gem5 Developers        ''' + ccCode + '''
61310037SARM gem5 Developers            } else {
61410037SARM gem5 Developers                CondCodesNZ = (defCc >> 2) & 0x3;
61510037SARM gem5 Developers                CondCodesC = (defCc >> 1) & 0x1;
61610037SARM gem5 Developers                CondCodesV = defCc & 0x1;
61710037SARM gem5 Developers            }
61810037SARM gem5 Developers        '''
61910037SARM gem5 Developers
62010037SARM gem5 Developers    buildDataXCondImmInst("ccmn", condCompCode("add", "+", True))
62110037SARM gem5 Developers    buildDataXCondImmInst("ccmp", condCompCode("sub", "-", True))
62210037SARM gem5 Developers    buildDataXCondRegInst("ccmn", condCompCode("add", "+", False))
62310037SARM gem5 Developers    buildDataXCondRegInst("ccmp", condCompCode("sub", "-", False))
62410037SARM gem5 Developers
62510037SARM gem5 Developers    condSelCode = '''
62610037SARM gem5 Developers        if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) {
62710037SARM gem5 Developers            Dest64 = Op164;
62810037SARM gem5 Developers        } else {
62910037SARM gem5 Developers            Dest64 = %(altVal)s;
63010037SARM gem5 Developers        }
63110037SARM gem5 Developers    '''
63210037SARM gem5 Developers    buildDataXCondSelInst("csel", condSelCode % {"altVal" : "Op264"})
63310037SARM gem5 Developers    buildDataXCondSelInst("csinc", condSelCode % {"altVal" : "Op264 + 1"})
63410037SARM gem5 Developers    buildDataXCondSelInst("csinv", condSelCode % {"altVal" : "~Op264"})
63510037SARM gem5 Developers    buildDataXCondSelInst("csneg", condSelCode % {"altVal" : "-Op264"})
63610037SARM gem5 Developers}};
637