110037SARM gem5 Developers// -*- mode: c++ -*-
210037SARM gem5 Developers
313120SEdmund.Grimley-Evans@arm.com// Copyright (c) 2012-2013, 2015-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: Giacomo Gabrielli
3910037SARM gem5 Developers//          Mbou Eyole
4010037SARM gem5 Developers
4110037SARM gem5 Developerslet {{
4210037SARM gem5 Developers
4310037SARM gem5 Developers    header_output = ""
4410037SARM gem5 Developers    exec_output = ""
4511165SRekai.GonzalezAlberquilla@arm.com    decoders = { 'Generic' : {} }
4610037SARM gem5 Developers
4710037SARM gem5 Developers    # FP types (FP operations always work with unsigned representations)
4813120SEdmund.Grimley-Evans@arm.com    floatTypes = ("uint16_t", "uint32_t", "uint64_t")
4910037SARM gem5 Developers    smallFloatTypes = ("uint32_t",)
5010037SARM gem5 Developers
5113759Sgiacomo.gabrielli@arm.com    zeroSveVecRegUpperPartCode = '''
5213759Sgiacomo.gabrielli@arm.com        TheISA::ISA::zeroSveVecRegUpperPart(%s,
5313759Sgiacomo.gabrielli@arm.com            ArmStaticInst::getCurSveVecLen<uint64_t>(xc->tcBase()));
5413759Sgiacomo.gabrielli@arm.com    '''
5513759Sgiacomo.gabrielli@arm.com
5610037SARM gem5 Developers    def threeEqualRegInstX(name, Name, opClass, types, rCount, op,
5710037SARM gem5 Developers                           readDest=False, pairwise=False, scalar=False,
5811165SRekai.GonzalezAlberquilla@arm.com                           byElem=False, decoder='Generic'):
5910037SARM gem5 Developers        assert (not pairwise) or ((not byElem) and (not scalar))
6011165SRekai.GonzalezAlberquilla@arm.com        global header_output, exec_output, decoders
6110037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
6210037SARM gem5 Developers        RegVect srcReg1, destReg;
6310037SARM gem5 Developers        '''
6410037SARM gem5 Developers        if byElem:
6510037SARM gem5 Developers            # 2nd register operand has to be read fully
6610037SARM gem5 Developers            eWalkCode += '''
6710037SARM gem5 Developers        FullRegVect srcReg2;
6810037SARM gem5 Developers        '''
6910037SARM gem5 Developers        else:
7010037SARM gem5 Developers            eWalkCode += '''
7110037SARM gem5 Developers        RegVect srcReg2;
7210037SARM gem5 Developers        '''
7310037SARM gem5 Developers        for reg in range(rCount):
7410037SARM gem5 Developers            eWalkCode += '''
7510037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
7610037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(reg)d_uw);
7710037SARM gem5 Developers        ''' % { "reg" : reg }
7810037SARM gem5 Developers            if readDest:
7910037SARM gem5 Developers                eWalkCode += '''
8010037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
8110037SARM gem5 Developers        ''' % { "reg" : reg }
8210037SARM gem5 Developers        if byElem:
8310037SARM gem5 Developers            # 2nd operand has to be read fully
8410037SARM gem5 Developers            for reg in range(rCount, 4):
8510037SARM gem5 Developers                eWalkCode += '''
8610037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(reg)d_uw);
8710037SARM gem5 Developers        ''' % { "reg" : reg }
8810037SARM gem5 Developers        readDestCode = ''
8910037SARM gem5 Developers        if readDest:
9010037SARM gem5 Developers            readDestCode = 'destElem = gtoh(destReg.elements[i]);'
9110037SARM gem5 Developers        if pairwise:
9210037SARM gem5 Developers            eWalkCode += '''
9310037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
9410037SARM gem5 Developers            Element srcElem1 = gtoh(2 * i < eCount ?
9510037SARM gem5 Developers                                    srcReg1.elements[2 * i] :
9610037SARM gem5 Developers                                    srcReg2.elements[2 * i - eCount]);
9710037SARM gem5 Developers            Element srcElem2 = gtoh(2 * i < eCount ?
9810037SARM gem5 Developers                                    srcReg1.elements[2 * i + 1] :
9910037SARM gem5 Developers                                    srcReg2.elements[2 * i + 1 - eCount]);
10010037SARM gem5 Developers            Element destElem;
10110037SARM gem5 Developers            %(readDest)s
10210037SARM gem5 Developers            %(op)s
10310037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
10410037SARM gem5 Developers        }
10510037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode }
10610037SARM gem5 Developers        else:
10710037SARM gem5 Developers            scalarCheck = '''
10810037SARM gem5 Developers            if (i != 0) {
10910037SARM gem5 Developers                destReg.elements[i] = 0;
11010037SARM gem5 Developers                continue;
11110037SARM gem5 Developers            }
11210037SARM gem5 Developers            '''
11310037SARM gem5 Developers            eWalkCode += '''
11410037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
11510037SARM gem5 Developers            %(scalarCheck)s
11610037SARM gem5 Developers            Element srcElem1 = gtoh(srcReg1.elements[i]);
11710037SARM gem5 Developers            Element srcElem2 = gtoh(srcReg2.elements[%(src2Index)s]);
11810037SARM gem5 Developers            Element destElem;
11910037SARM gem5 Developers            %(readDest)s
12010037SARM gem5 Developers            %(op)s
12110037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
12210037SARM gem5 Developers        }
12310037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode,
12410037SARM gem5 Developers                "scalarCheck" : scalarCheck if scalar else "",
12510037SARM gem5 Developers                "src2Index" : "imm" if byElem else "i" }
12610037SARM gem5 Developers        for reg in range(rCount):
12710037SARM gem5 Developers            eWalkCode += '''
12810037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
12910037SARM gem5 Developers        ''' % { "reg" : reg }
13010037SARM gem5 Developers        if rCount < 4:  # zero upper half
13110037SARM gem5 Developers            for reg in range(rCount, 4):
13210037SARM gem5 Developers                eWalkCode += '''
13310037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
13410037SARM gem5 Developers        ''' % { "reg" : reg }
13510037SARM gem5 Developers        iop = InstObjParams(name, Name,
13610037SARM gem5 Developers                            "DataX2RegImmOp" if byElem else "DataX2RegOp",
13710037SARM gem5 Developers                            { "code": eWalkCode,
13810037SARM gem5 Developers                              "r_count": rCount,
13910037SARM gem5 Developers                              "op_class": opClass }, [])
14013759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
14110037SARM gem5 Developers        if byElem:
14210037SARM gem5 Developers            header_output += NeonX2RegImmOpDeclare.subst(iop)
14310037SARM gem5 Developers        else:
14410037SARM gem5 Developers            header_output += NeonX2RegOpDeclare.subst(iop)
14510037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
14610037SARM gem5 Developers        for type in types:
14710037SARM gem5 Developers            substDict = { "targs" : type,
14810037SARM gem5 Developers                          "class_name" : Name }
14910037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
15010037SARM gem5 Developers
15110037SARM gem5 Developers    def threeUnequalRegInstX(name, Name, opClass, types, op,
15210037SARM gem5 Developers                             bigSrc1, bigSrc2, bigDest, readDest, scalar=False,
15310037SARM gem5 Developers                             byElem=False, hi=False):
15410037SARM gem5 Developers        assert not (scalar and hi)
15510037SARM gem5 Developers        global header_output, exec_output
15610037SARM gem5 Developers        src1Cnt = src2Cnt = destCnt = 2
15710037SARM gem5 Developers        src1Prefix = src2Prefix = destPrefix = ''
15810037SARM gem5 Developers        if bigSrc1:
15910037SARM gem5 Developers            src1Cnt = 4
16010037SARM gem5 Developers            src1Prefix = 'Big'
16110037SARM gem5 Developers        if bigSrc2:
16210037SARM gem5 Developers            src2Cnt = 4
16310037SARM gem5 Developers            src2Prefix = 'Big'
16410037SARM gem5 Developers        if bigDest:
16510037SARM gem5 Developers            destCnt = 4
16610037SARM gem5 Developers            destPrefix = 'Big'
16710037SARM gem5 Developers        if byElem:
16810037SARM gem5 Developers            src2Prefix = 'Full'
16910037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
17010037SARM gem5 Developers        %sRegVect srcReg1;
17110037SARM gem5 Developers        %sRegVect srcReg2;
17210037SARM gem5 Developers        %sRegVect destReg;
17310037SARM gem5 Developers        ''' % (src1Prefix, src2Prefix, destPrefix)
17410037SARM gem5 Developers        srcReg1 = 0
17510037SARM gem5 Developers        if hi and not bigSrc1:  # long/widening operations
17610037SARM gem5 Developers            srcReg1 = 2
17710037SARM gem5 Developers        for reg in range(src1Cnt):
17810037SARM gem5 Developers            eWalkCode += '''
17910037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(srcReg1)d_uw);
18010037SARM gem5 Developers        ''' % { "reg" : reg, "srcReg1" : srcReg1 }
18110037SARM gem5 Developers            srcReg1 += 1
18210037SARM gem5 Developers        srcReg2 = 0
18310037SARM gem5 Developers        if (not byElem) and (hi and not bigSrc2):  # long/widening operations
18410037SARM gem5 Developers            srcReg2 = 2
18510037SARM gem5 Developers        for reg in range(src2Cnt):
18610037SARM gem5 Developers            eWalkCode += '''
18710037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(srcReg2)d_uw);
18810037SARM gem5 Developers        ''' % { "reg" : reg, "srcReg2" : srcReg2 }
18910037SARM gem5 Developers            srcReg2 += 1
19010037SARM gem5 Developers        if byElem:
19110037SARM gem5 Developers            # 2nd operand has to be read fully
19210037SARM gem5 Developers            for reg in range(src2Cnt, 4):
19310037SARM gem5 Developers                eWalkCode += '''
19410037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(reg)d_uw);
19510037SARM gem5 Developers        ''' % { "reg" : reg }
19610037SARM gem5 Developers        if readDest:
19710037SARM gem5 Developers            for reg in range(destCnt):
19810037SARM gem5 Developers                eWalkCode += '''
19910037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
20010037SARM gem5 Developers        ''' % { "reg" : reg }
20110037SARM gem5 Developers        readDestCode = ''
20210037SARM gem5 Developers        if readDest:
20310037SARM gem5 Developers            readDestCode = 'destElem = gtoh(destReg.elements[i]);'
20410037SARM gem5 Developers        scalarCheck = '''
20510037SARM gem5 Developers            if (i != 0) {
20610037SARM gem5 Developers                destReg.elements[i] = 0;
20710037SARM gem5 Developers                continue;
20810037SARM gem5 Developers            }
20910037SARM gem5 Developers            '''
21010037SARM gem5 Developers        eWalkCode += '''
21110037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
21210037SARM gem5 Developers            %(scalarCheck)s
21310037SARM gem5 Developers            %(src1Prefix)sElement srcElem1 = gtoh(srcReg1.elements[i]);
21410037SARM gem5 Developers            %(src1Prefix)sElement srcElem2 = gtoh(srcReg2.elements[%(src2Index)s]);
21510037SARM gem5 Developers            %(destPrefix)sElement destElem;
21610037SARM gem5 Developers            %(readDest)s
21710037SARM gem5 Developers            %(op)s
21810037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
21910037SARM gem5 Developers        }
22010037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode,
22110037SARM gem5 Developers                "src1Prefix" : src1Prefix, "src2Prefix" : src2Prefix,
22210037SARM gem5 Developers                "destPrefix" : destPrefix,
22310037SARM gem5 Developers                "scalarCheck" : scalarCheck if scalar else "",
22410037SARM gem5 Developers                "src2Index" : "imm" if byElem else "i" }
22510037SARM gem5 Developers        destReg = 0
22610037SARM gem5 Developers        if hi and not bigDest:
22710037SARM gem5 Developers            # narrowing operations
22810037SARM gem5 Developers            destReg = 2
22910037SARM gem5 Developers        for reg in range(destCnt):
23010037SARM gem5 Developers            eWalkCode += '''
23110037SARM gem5 Developers        AA64FpDestP%(destReg)d_uw = gtoh(destReg.regs[%(reg)d]);
23210037SARM gem5 Developers        ''' % { "reg" : reg, "destReg": destReg }
23310037SARM gem5 Developers            destReg += 1
23412110SRekai.GonzalezAlberquilla@arm.com        if destCnt < 4:
23512110SRekai.GonzalezAlberquilla@arm.com            if hi:  # Explicitly merge with lower half
23612110SRekai.GonzalezAlberquilla@arm.com                for reg in range(0, destCnt):
23712110SRekai.GonzalezAlberquilla@arm.com                    eWalkCode += '''
23812110SRekai.GonzalezAlberquilla@arm.com        AA64FpDestP%(reg)d_uw = AA64FpDestP%(reg)d_uw;''' % { "reg" : reg }
23912110SRekai.GonzalezAlberquilla@arm.com            else:  # zero upper half
24012110SRekai.GonzalezAlberquilla@arm.com                for reg in range(destCnt, 4):
24112110SRekai.GonzalezAlberquilla@arm.com                    eWalkCode += '''
24212110SRekai.GonzalezAlberquilla@arm.com        AA64FpDestP%(reg)d_uw = 0;''' % { "reg" : reg }
24312110SRekai.GonzalezAlberquilla@arm.com
24410037SARM gem5 Developers        iop = InstObjParams(name, Name,
24510037SARM gem5 Developers                            "DataX2RegImmOp" if byElem else "DataX2RegOp",
24610037SARM gem5 Developers                            { "code": eWalkCode,
24710037SARM gem5 Developers                              "r_count": 2,
24810037SARM gem5 Developers                              "op_class": opClass }, [])
24913759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
25010037SARM gem5 Developers        if byElem:
25110037SARM gem5 Developers            header_output += NeonX2RegImmOpDeclare.subst(iop)
25210037SARM gem5 Developers        else:
25310037SARM gem5 Developers            header_output += NeonX2RegOpDeclare.subst(iop)
25410037SARM gem5 Developers        exec_output += NeonXUnequalRegOpExecute.subst(iop)
25510037SARM gem5 Developers        for type in types:
25610037SARM gem5 Developers            substDict = { "targs" : type,
25710037SARM gem5 Developers                          "class_name" : Name }
25810037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
25910037SARM gem5 Developers
26010037SARM gem5 Developers    def threeRegNarrowInstX(name, Name, opClass, types, op, readDest=False,
26110037SARM gem5 Developers                            scalar=False, byElem=False, hi=False):
26210037SARM gem5 Developers        assert not byElem
26310037SARM gem5 Developers        threeUnequalRegInstX(name, Name, opClass, types, op,
26410037SARM gem5 Developers                             True, True, False, readDest, scalar, byElem, hi)
26510037SARM gem5 Developers
26610037SARM gem5 Developers    def threeRegLongInstX(name, Name, opClass, types, op, readDest=False,
26710037SARM gem5 Developers                          scalar=False, byElem=False, hi=False):
26810037SARM gem5 Developers        threeUnequalRegInstX(name, Name, opClass, types, op,
26910037SARM gem5 Developers                             False, False, True, readDest, scalar, byElem, hi)
27010037SARM gem5 Developers
27110037SARM gem5 Developers    def threeRegWideInstX(name, Name, opClass, types, op, readDest=False,
27210037SARM gem5 Developers                          scalar=False, byElem=False, hi=False):
27310037SARM gem5 Developers        assert not byElem
27410037SARM gem5 Developers        threeUnequalRegInstX(name, Name, opClass, types, op,
27510037SARM gem5 Developers                             True, False, True, readDest, scalar, byElem, hi)
27610037SARM gem5 Developers
27710037SARM gem5 Developers    def twoEqualRegInstX(name, Name, opClass, types, rCount, op,
27810037SARM gem5 Developers                         readDest=False, scalar=False, byElem=False,
27910037SARM gem5 Developers                         hasImm=False, isDup=False):
28010037SARM gem5 Developers        global header_output, exec_output
28110037SARM gem5 Developers        assert (not isDup) or byElem
28210037SARM gem5 Developers        if byElem:
28310037SARM gem5 Developers            hasImm = True
28410037SARM gem5 Developers        if isDup:
28510037SARM gem5 Developers            eWalkCode = simd64EnabledCheckCode + '''
28610037SARM gem5 Developers        FullRegVect srcReg1;
28710037SARM gem5 Developers        RegVect destReg;
28810037SARM gem5 Developers        '''
28910037SARM gem5 Developers        else:
29010037SARM gem5 Developers            eWalkCode = simd64EnabledCheckCode + '''
29110037SARM gem5 Developers        RegVect srcReg1, destReg;
29210037SARM gem5 Developers        '''
29310037SARM gem5 Developers        for reg in range(4 if isDup else rCount):
29410037SARM gem5 Developers            eWalkCode += '''
29510037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
29610037SARM gem5 Developers        ''' % { "reg" : reg }
29710037SARM gem5 Developers            if readDest:
29810037SARM gem5 Developers                eWalkCode += '''
29910037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
30010037SARM gem5 Developers        ''' % { "reg" : reg }
30110037SARM gem5 Developers        readDestCode = ''
30210037SARM gem5 Developers        if readDest:
30310037SARM gem5 Developers            readDestCode = 'destElem = gtoh(destReg.elements[i]);'
30410037SARM gem5 Developers        scalarCheck = '''
30510037SARM gem5 Developers            if (i != 0) {
30610037SARM gem5 Developers                destReg.elements[i] = 0;
30710037SARM gem5 Developers                continue;
30810037SARM gem5 Developers            }
30910037SARM gem5 Developers            '''
31010037SARM gem5 Developers        eWalkCode += '''
31110037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
31210037SARM gem5 Developers            %(scalarCheck)s
31310037SARM gem5 Developers            unsigned j = i;
31410037SARM gem5 Developers            Element srcElem1 = gtoh(srcReg1.elements[%(src1Index)s]);
31510037SARM gem5 Developers            Element destElem;
31610037SARM gem5 Developers            %(readDest)s
31710037SARM gem5 Developers            %(op)s
31810037SARM gem5 Developers            destReg.elements[j] = htog(destElem);
31910037SARM gem5 Developers        }
32010037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode,
32110037SARM gem5 Developers                "scalarCheck" : scalarCheck if scalar else "",
32210037SARM gem5 Developers                "src1Index" : "imm" if byElem else "i" }
32310037SARM gem5 Developers        for reg in range(rCount):
32410037SARM gem5 Developers            eWalkCode += '''
32510037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
32610037SARM gem5 Developers        ''' % { "reg" : reg }
32710037SARM gem5 Developers        if rCount < 4:  # zero upper half
32810037SARM gem5 Developers            for reg in range(rCount, 4):
32910037SARM gem5 Developers                eWalkCode += '''
33010037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
33110037SARM gem5 Developers        ''' % { "reg" : reg }
33210037SARM gem5 Developers        iop = InstObjParams(name, Name,
33310037SARM gem5 Developers                            "DataX1RegImmOp" if hasImm else "DataX1RegOp",
33410037SARM gem5 Developers                            { "code": eWalkCode,
33510037SARM gem5 Developers                              "r_count": rCount,
33610037SARM gem5 Developers                              "op_class": opClass }, [])
33713759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
33810037SARM gem5 Developers        if hasImm:
33910037SARM gem5 Developers            header_output += NeonX1RegImmOpDeclare.subst(iop)
34010037SARM gem5 Developers        else:
34110037SARM gem5 Developers            header_output += NeonX1RegOpDeclare.subst(iop)
34210037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
34310037SARM gem5 Developers        for type in types:
34410037SARM gem5 Developers            substDict = { "targs" : type,
34510037SARM gem5 Developers                          "class_name" : Name }
34610037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
34710037SARM gem5 Developers
34810037SARM gem5 Developers    def twoRegLongInstX(name, Name, opClass, types, op, readDest=False,
34910037SARM gem5 Developers                        hi=False, hasImm=False):
35010037SARM gem5 Developers        global header_output, exec_output
35110037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
35210037SARM gem5 Developers        RegVect srcReg1;
35310037SARM gem5 Developers        BigRegVect destReg;
35410037SARM gem5 Developers        '''
35510037SARM gem5 Developers        destReg = 0 if not hi else 2
35610037SARM gem5 Developers        for reg in range(2):
35710037SARM gem5 Developers            eWalkCode += '''
35810037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(destReg)d_uw);
35910037SARM gem5 Developers        ''' % { "reg" : reg, "destReg": destReg }
36010037SARM gem5 Developers            destReg += 1
36110037SARM gem5 Developers        destReg = 0 if not hi else 2
36210037SARM gem5 Developers        if readDest:
36310037SARM gem5 Developers            for reg in range(4):
36410037SARM gem5 Developers                eWalkCode += '''
36510037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
36610037SARM gem5 Developers        ''' % { "reg" : reg }
36710037SARM gem5 Developers                destReg += 1
36810037SARM gem5 Developers        readDestCode = ''
36910037SARM gem5 Developers        if readDest:
37010037SARM gem5 Developers            readDestCode = 'destReg = gtoh(destReg.elements[i]);'
37110037SARM gem5 Developers        eWalkCode += '''
37210037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
37310037SARM gem5 Developers            Element srcElem1 = gtoh(srcReg1.elements[i]);
37410037SARM gem5 Developers            BigElement destElem;
37510037SARM gem5 Developers            %(readDest)s
37610037SARM gem5 Developers            %(op)s
37710037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
37810037SARM gem5 Developers        }
37910037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode }
38010037SARM gem5 Developers        for reg in range(4):
38110037SARM gem5 Developers            eWalkCode += '''
38210037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
38310037SARM gem5 Developers        ''' % { "reg" : reg }
38410037SARM gem5 Developers        iop = InstObjParams(name, Name,
38510037SARM gem5 Developers                            "DataX1RegImmOp" if hasImm else "DataX1RegOp",
38610037SARM gem5 Developers                            { "code": eWalkCode,
38710037SARM gem5 Developers                              "r_count": 2,
38810037SARM gem5 Developers                              "op_class": opClass }, [])
38913759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
39010037SARM gem5 Developers        if hasImm:
39110037SARM gem5 Developers            header_output += NeonX1RegImmOpDeclare.subst(iop)
39210037SARM gem5 Developers        else:
39310037SARM gem5 Developers            header_output += NeonX1RegOpDeclare.subst(iop)
39410037SARM gem5 Developers        exec_output += NeonXUnequalRegOpExecute.subst(iop)
39510037SARM gem5 Developers        for type in types:
39610037SARM gem5 Developers            substDict = { "targs" : type,
39710037SARM gem5 Developers                          "class_name" : Name }
39810037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
39910037SARM gem5 Developers
40010037SARM gem5 Developers    def twoRegNarrowInstX(name, Name, opClass, types, op, readDest=False,
40110037SARM gem5 Developers                          scalar=False, hi=False, hasImm=False):
40210037SARM gem5 Developers        global header_output, exec_output
40310037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
40410037SARM gem5 Developers        BigRegVect srcReg1;
40510037SARM gem5 Developers        RegVect destReg;
40610037SARM gem5 Developers        '''
40710037SARM gem5 Developers        for reg in range(4):
40810037SARM gem5 Developers            eWalkCode += '''
40910037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
41010037SARM gem5 Developers        ''' % { "reg" : reg }
41110037SARM gem5 Developers        if readDest:
41210037SARM gem5 Developers            for reg in range(2):
41310037SARM gem5 Developers                eWalkCode += '''
41410037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
41510037SARM gem5 Developers        ''' % { "reg" : reg }
41610037SARM gem5 Developers        else:
41710037SARM gem5 Developers            eWalkCode += '''
41810037SARM gem5 Developers        destReg.elements[0] = 0;
41910037SARM gem5 Developers        ''' % { "reg" : reg }
42010037SARM gem5 Developers        readDestCode = ''
42110037SARM gem5 Developers        if readDest:
42210037SARM gem5 Developers            readDestCode = 'destElem = gtoh(destReg.elements[i]);'
42310037SARM gem5 Developers        scalarCheck = '''
42410037SARM gem5 Developers            if (i != 0) {
42510037SARM gem5 Developers                destReg.elements[i] = 0;
42610037SARM gem5 Developers                continue;
42710037SARM gem5 Developers            }
42810037SARM gem5 Developers            '''
42910037SARM gem5 Developers        eWalkCode += '''
43010037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
43110037SARM gem5 Developers            %(scalarCheck)s
43210037SARM gem5 Developers            BigElement srcElem1 = gtoh(srcReg1.elements[i]);
43310037SARM gem5 Developers            Element destElem;
43410037SARM gem5 Developers            %(readDest)s
43510037SARM gem5 Developers            %(op)s
43610037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
43710037SARM gem5 Developers        }
43810037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode,
43910037SARM gem5 Developers                "scalarCheck" : scalarCheck if scalar else "" }
44010037SARM gem5 Developers        destReg = 0 if not hi else 2
44110037SARM gem5 Developers        for reg in range(2):
44210037SARM gem5 Developers            eWalkCode += '''
44310037SARM gem5 Developers        AA64FpDestP%(destReg)d_uw = gtoh(destReg.regs[%(reg)d]);
44410037SARM gem5 Developers        ''' % { "reg" : reg, "destReg": destReg }
44510037SARM gem5 Developers            destReg += 1
44612110SRekai.GonzalezAlberquilla@arm.com        if hi:
44712110SRekai.GonzalezAlberquilla@arm.com            for reg in range(0, 2):  # Explicitly merge with the lower half
44812110SRekai.GonzalezAlberquilla@arm.com                eWalkCode += '''
44912110SRekai.GonzalezAlberquilla@arm.com        AA64FpDestP%(reg)d_uw = AA64FpDestP%(reg)d_uw;''' % { "reg" : reg }
45012110SRekai.GonzalezAlberquilla@arm.com        else:
45110037SARM gem5 Developers            for reg in range(2, 4):  # zero upper half
45210037SARM gem5 Developers                eWalkCode += '''
45310037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
45410037SARM gem5 Developers        ''' % { "reg" : reg }
45512110SRekai.GonzalezAlberquilla@arm.com
45610037SARM gem5 Developers        iop = InstObjParams(name, Name,
45710037SARM gem5 Developers                            "DataX1RegImmOp" if hasImm else "DataX1RegOp",
45810037SARM gem5 Developers                            { "code": eWalkCode,
45910037SARM gem5 Developers                              "r_count": 2,
46010037SARM gem5 Developers                              "op_class": opClass }, [])
46113759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
46210037SARM gem5 Developers        if hasImm:
46310037SARM gem5 Developers            header_output += NeonX1RegImmOpDeclare.subst(iop)
46410037SARM gem5 Developers        else:
46510037SARM gem5 Developers            header_output += NeonX1RegOpDeclare.subst(iop)
46610037SARM gem5 Developers        exec_output += NeonXUnequalRegOpExecute.subst(iop)
46710037SARM gem5 Developers        for type in types:
46810037SARM gem5 Developers            substDict = { "targs" : type,
46910037SARM gem5 Developers                          "class_name" : Name }
47010037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
47110037SARM gem5 Developers
47210037SARM gem5 Developers    def threeRegScrambleInstX(name, Name, opClass, types, rCount, op):
47310037SARM gem5 Developers        global header_output, exec_output
47410037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
47510037SARM gem5 Developers        RegVect srcReg1, srcReg2, destReg;
47610037SARM gem5 Developers        '''
47710037SARM gem5 Developers        for reg in range(rCount):
47810037SARM gem5 Developers            eWalkCode += '''
47910037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
48010037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(reg)d_uw);
48110037SARM gem5 Developers        ''' % { "reg" : reg }
48210037SARM gem5 Developers        eWalkCode += op
48310037SARM gem5 Developers        for reg in range(rCount):
48410037SARM gem5 Developers            eWalkCode += '''
48510037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
48610037SARM gem5 Developers        ''' % { "reg" : reg }
48710037SARM gem5 Developers        if rCount < 4:
48810037SARM gem5 Developers            for reg in range(rCount, 4):
48910037SARM gem5 Developers                eWalkCode += '''
49010037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
49110037SARM gem5 Developers        ''' % { "reg" : reg }
49210037SARM gem5 Developers        iop = InstObjParams(name, Name,
49310037SARM gem5 Developers                            "DataX2RegOp",
49410037SARM gem5 Developers                            { "code": eWalkCode,
49510037SARM gem5 Developers                              "r_count": rCount,
49610037SARM gem5 Developers                              "op_class": opClass }, [])
49713759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
49810037SARM gem5 Developers        header_output += NeonX2RegOpDeclare.subst(iop)
49910037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
50010037SARM gem5 Developers        for type in types:
50110037SARM gem5 Developers            substDict = { "targs" : type,
50210037SARM gem5 Developers                          "class_name" : Name }
50310037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
50410037SARM gem5 Developers
50510037SARM gem5 Developers    def insFromVecElemInstX(name, Name, opClass, types, rCount):
50610037SARM gem5 Developers        global header_output, exec_output
50710037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
50810037SARM gem5 Developers        FullRegVect srcReg1;
50910037SARM gem5 Developers        RegVect destReg;
51010037SARM gem5 Developers        '''
51110037SARM gem5 Developers        for reg in range(4):
51210037SARM gem5 Developers            eWalkCode += '''
51310037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
51410037SARM gem5 Developers        ''' % { "reg" : reg }
51510037SARM gem5 Developers        for reg in range(rCount):
51610037SARM gem5 Developers            eWalkCode += '''
51710037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
51810037SARM gem5 Developers        ''' % { "reg" : reg }
51910037SARM gem5 Developers        eWalkCode += '''
52010037SARM gem5 Developers        Element srcElem1 = gtoh(srcReg1.elements[imm2]);
52110037SARM gem5 Developers        Element destElem = srcElem1;
52210037SARM gem5 Developers        destReg.elements[imm1] = htog(destElem);
52310037SARM gem5 Developers        '''
52410037SARM gem5 Developers        for reg in range(rCount):
52510037SARM gem5 Developers            eWalkCode += '''
52610037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
52710037SARM gem5 Developers        ''' % { "reg" : reg }
52810037SARM gem5 Developers        iop = InstObjParams(name, Name,
52910037SARM gem5 Developers                            "DataX1Reg2ImmOp",
53010037SARM gem5 Developers                            { "code": eWalkCode,
53110037SARM gem5 Developers                              "r_count": rCount,
53210037SARM gem5 Developers                              "op_class": opClass }, [])
53313759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
53410037SARM gem5 Developers        header_output += NeonX1Reg2ImmOpDeclare.subst(iop)
53510037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
53610037SARM gem5 Developers        for type in types:
53710037SARM gem5 Developers            substDict = { "targs" : type,
53810037SARM gem5 Developers                          "class_name" : Name }
53910037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
54010037SARM gem5 Developers
54110037SARM gem5 Developers    def twoRegPairwiseScInstX(name, Name, opClass, types, rCount, op):
54210037SARM gem5 Developers        global header_output, exec_output
54310037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
54410037SARM gem5 Developers        RegVect srcReg1, destReg;
54510037SARM gem5 Developers        '''
54610037SARM gem5 Developers        for reg in range(rCount):
54710037SARM gem5 Developers            eWalkCode += '''
54810037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
54910037SARM gem5 Developers        ''' % { "reg" : reg }
55010037SARM gem5 Developers        eWalkCode += '''
55110037SARM gem5 Developers        Element srcElem1 = gtoh(srcReg1.elements[0]);
55210037SARM gem5 Developers        Element srcElem2 = gtoh(srcReg1.elements[1]);
55310037SARM gem5 Developers        Element destElem;
55410037SARM gem5 Developers        %(op)s
55510037SARM gem5 Developers        destReg.elements[0] = htog(destElem);
55610037SARM gem5 Developers        ''' % { "op" : op }
55710037SARM gem5 Developers        destCnt = rCount / 2
55810037SARM gem5 Developers        for reg in range(destCnt):
55910037SARM gem5 Developers            eWalkCode += '''
56010037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
56110037SARM gem5 Developers        ''' % { "reg" : reg }
56210037SARM gem5 Developers        for reg in range(destCnt, 4):  # zero upper half
56310037SARM gem5 Developers            eWalkCode += '''
56410037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
56510037SARM gem5 Developers        ''' % { "reg" : reg }
56610037SARM gem5 Developers        iop = InstObjParams(name, Name,
56710037SARM gem5 Developers                            "DataX1RegOp",
56810037SARM gem5 Developers                            { "code": eWalkCode,
56910037SARM gem5 Developers                              "r_count": rCount,
57010037SARM gem5 Developers                              "op_class": opClass }, [])
57113759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
57210037SARM gem5 Developers        header_output += NeonX1RegOpDeclare.subst(iop)
57310037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
57410037SARM gem5 Developers        for type in types:
57510037SARM gem5 Developers            substDict = { "targs" : type,
57610037SARM gem5 Developers                          "class_name" : Name }
57710037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
57810037SARM gem5 Developers
57910037SARM gem5 Developers    def twoRegAcrossInstX(name, Name, opClass, types, rCount, op,
58010037SARM gem5 Developers                          doubleDest=False, long=False):
58110037SARM gem5 Developers        global header_output, exec_output
58210037SARM gem5 Developers        destPrefix = "Big" if long else ""
58310037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
58410037SARM gem5 Developers        RegVect srcReg1;
58510037SARM gem5 Developers        %sRegVect destReg;
58610037SARM gem5 Developers        ''' % destPrefix
58710037SARM gem5 Developers        for reg in range(rCount):
58810037SARM gem5 Developers            eWalkCode += '''
58910037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
59010037SARM gem5 Developers        ''' % { "reg" : reg }
59110037SARM gem5 Developers        eWalkCode += '''
59210037SARM gem5 Developers        destReg.regs[0] = 0;
59310037SARM gem5 Developers        %(destPrefix)sElement destElem = 0;
59410037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
59510037SARM gem5 Developers            Element srcElem1 = gtoh(srcReg1.elements[i]);
59610037SARM gem5 Developers            if (i == 0) {
59710037SARM gem5 Developers                destElem = srcElem1;
59810037SARM gem5 Developers            } else {
59910037SARM gem5 Developers                %(op)s
60010037SARM gem5 Developers            }
60110037SARM gem5 Developers        }
60210037SARM gem5 Developers        destReg.elements[0] = htog(destElem);
60310037SARM gem5 Developers        ''' % { "op" : op, "destPrefix" : destPrefix }
60410037SARM gem5 Developers        destCnt = 2 if doubleDest else 1
60510037SARM gem5 Developers        for reg in range(destCnt):
60610037SARM gem5 Developers            eWalkCode += '''
60710037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
60810037SARM gem5 Developers        ''' % { "reg" : reg }
60910037SARM gem5 Developers        for reg in range(destCnt, 4):  # zero upper half
61010037SARM gem5 Developers            eWalkCode += '''
61110037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
61210037SARM gem5 Developers        ''' % { "reg" : reg }
61310037SARM gem5 Developers        iop = InstObjParams(name, Name,
61410037SARM gem5 Developers                            "DataX1RegOp",
61510037SARM gem5 Developers                            { "code": eWalkCode,
61610037SARM gem5 Developers                              "r_count": rCount,
61710037SARM gem5 Developers                              "op_class": opClass }, [])
61813759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
61910037SARM gem5 Developers        header_output += NeonX1RegOpDeclare.subst(iop)
62010037SARM gem5 Developers        if long:
62110037SARM gem5 Developers            exec_output += NeonXUnequalRegOpExecute.subst(iop)
62210037SARM gem5 Developers        else:
62310037SARM gem5 Developers            exec_output += NeonXEqualRegOpExecute.subst(iop)
62410037SARM gem5 Developers        for type in types:
62510037SARM gem5 Developers            substDict = { "targs" : type,
62610037SARM gem5 Developers                          "class_name" : Name }
62710037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
62810037SARM gem5 Developers
62910037SARM gem5 Developers    def twoRegCondenseInstX(name, Name, opClass, types, rCount, op,
63010037SARM gem5 Developers                            readDest=False):
63110037SARM gem5 Developers        global header_output, exec_output
63210037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
63310037SARM gem5 Developers        RegVect srcRegs;
63410037SARM gem5 Developers        BigRegVect destReg;
63510037SARM gem5 Developers        '''
63610037SARM gem5 Developers        for reg in range(rCount):
63710037SARM gem5 Developers            eWalkCode += '''
63810037SARM gem5 Developers        srcRegs.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
63910037SARM gem5 Developers        ''' % { "reg" : reg }
64010037SARM gem5 Developers            if readDest:
64110037SARM gem5 Developers                eWalkCode += '''
64210037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
64310037SARM gem5 Developers        ''' % { "reg" : reg }
64410037SARM gem5 Developers        readDestCode = ''
64510037SARM gem5 Developers        if readDest:
64610037SARM gem5 Developers            readDestCode = 'destElem = gtoh(destReg.elements[i]);'
64710037SARM gem5 Developers        eWalkCode += '''
64810037SARM gem5 Developers        for (unsigned i = 0; i < eCount / 2; i++) {
64910037SARM gem5 Developers            Element srcElem1 = gtoh(srcRegs.elements[2 * i]);
65010037SARM gem5 Developers            Element srcElem2 = gtoh(srcRegs.elements[2 * i + 1]);
65110037SARM gem5 Developers            BigElement destElem;
65210037SARM gem5 Developers            %(readDest)s
65310037SARM gem5 Developers            %(op)s
65410037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
65510037SARM gem5 Developers        }
65610037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode }
65710037SARM gem5 Developers        for reg in range(rCount):
65810037SARM gem5 Developers            eWalkCode += '''
65910037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
66010037SARM gem5 Developers        ''' % { "reg" : reg }
66110037SARM gem5 Developers        if rCount < 4:  # zero upper half
66210037SARM gem5 Developers            for reg in range(rCount, 4):
66310037SARM gem5 Developers                eWalkCode += '''
66410037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
66510037SARM gem5 Developers        ''' % { "reg" : reg }
66610037SARM gem5 Developers        iop = InstObjParams(name, Name,
66710037SARM gem5 Developers                            "DataX1RegOp",
66810037SARM gem5 Developers                            { "code": eWalkCode,
66910037SARM gem5 Developers                              "r_count": rCount,
67010037SARM gem5 Developers                              "op_class": opClass }, [])
67113759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
67210037SARM gem5 Developers        header_output += NeonX1RegOpDeclare.subst(iop)
67310037SARM gem5 Developers        exec_output += NeonXUnequalRegOpExecute.subst(iop)
67410037SARM gem5 Developers        for type in types:
67510037SARM gem5 Developers            substDict = { "targs" : type,
67610037SARM gem5 Developers                          "class_name" : Name }
67710037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
67810037SARM gem5 Developers
67910037SARM gem5 Developers    def oneRegImmInstX(name, Name, opClass, types, rCount, op, readDest=False):
68010037SARM gem5 Developers        global header_output, exec_output
68110037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
68210037SARM gem5 Developers        RegVect destReg;
68310037SARM gem5 Developers        '''
68410037SARM gem5 Developers        if readDest:
68510037SARM gem5 Developers            for reg in range(rCount):
68610037SARM gem5 Developers                eWalkCode += '''
68710037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
68810037SARM gem5 Developers        ''' % { "reg" : reg }
68910037SARM gem5 Developers        readDestCode = ''
69010037SARM gem5 Developers        if readDest:
69110037SARM gem5 Developers            readDestCode = 'destElem = gtoh(destReg.elements[i]);'
69210037SARM gem5 Developers        eWalkCode += '''
69310037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
69410037SARM gem5 Developers            Element destElem;
69510037SARM gem5 Developers            %(readDest)s
69610037SARM gem5 Developers            %(op)s
69710037SARM gem5 Developers            destReg.elements[i] = htog(destElem);
69810037SARM gem5 Developers        }
69910037SARM gem5 Developers        ''' % { "op" : op, "readDest" : readDestCode }
70010037SARM gem5 Developers        for reg in range(rCount):
70110037SARM gem5 Developers            eWalkCode += '''
70210037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
70310037SARM gem5 Developers        ''' % { "reg" : reg }
70410037SARM gem5 Developers        if rCount < 4:  # zero upper half
70510037SARM gem5 Developers            for reg in range(rCount, 4):
70610037SARM gem5 Developers                eWalkCode += '''
70710037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
70810037SARM gem5 Developers        ''' % { "reg" : reg }
70910037SARM gem5 Developers        iop = InstObjParams(name, Name,
71010037SARM gem5 Developers                            "DataXImmOnlyOp",
71110037SARM gem5 Developers                            { "code": eWalkCode,
71210037SARM gem5 Developers                              "r_count": rCount,
71310037SARM gem5 Developers                              "op_class": opClass }, [])
71413759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
71510037SARM gem5 Developers        header_output += NeonX1RegImmOnlyOpDeclare.subst(iop)
71610037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
71710037SARM gem5 Developers        for type in types:
71810037SARM gem5 Developers            substDict = { "targs" : type,
71910037SARM gem5 Developers                          "class_name" : Name }
72010037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
72110037SARM gem5 Developers
72210037SARM gem5 Developers    def dupGprInstX(name, Name, opClass, types, rCount, gprSpec):
72310037SARM gem5 Developers        global header_output, exec_output
72410037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
72510037SARM gem5 Developers        RegVect destReg;
72610037SARM gem5 Developers        for (unsigned i = 0; i < eCount; i++) {
72710037SARM gem5 Developers            destReg.elements[i] = htog((Element) %sOp1);
72810037SARM gem5 Developers        }
72910037SARM gem5 Developers        ''' % gprSpec
73010037SARM gem5 Developers        for reg in range(rCount):
73110037SARM gem5 Developers            eWalkCode += '''
73210037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
73310037SARM gem5 Developers        ''' % { "reg" : reg }
73410037SARM gem5 Developers        if rCount < 4:  # zero upper half
73510037SARM gem5 Developers            for reg in range(rCount, 4):
73610037SARM gem5 Developers                eWalkCode += '''
73710037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
73810037SARM gem5 Developers        ''' % { "reg" : reg }
73910037SARM gem5 Developers        iop = InstObjParams(name, Name,
74010037SARM gem5 Developers                            "DataX1RegOp",
74110037SARM gem5 Developers                            { "code": eWalkCode,
74210037SARM gem5 Developers                              "r_count": rCount,
74310037SARM gem5 Developers                              "op_class": opClass }, [])
74413759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
74510037SARM gem5 Developers        header_output += NeonX1RegOpDeclare.subst(iop)
74610037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
74710037SARM gem5 Developers        for type in types:
74810037SARM gem5 Developers            substDict = { "targs" : type,
74910037SARM gem5 Developers                          "class_name" : Name }
75010037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
75110037SARM gem5 Developers
75210037SARM gem5 Developers    def extInstX(name, Name, opClass, types, rCount, op):
75310037SARM gem5 Developers        global header_output, exec_output
75410037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
75510037SARM gem5 Developers        RegVect srcReg1, srcReg2, destReg;
75610037SARM gem5 Developers        '''
75710037SARM gem5 Developers        for reg in range(rCount):
75810037SARM gem5 Developers            eWalkCode += '''
75910037SARM gem5 Developers        srcReg1.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
76010037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(reg)d_uw);
76110037SARM gem5 Developers        ''' % { "reg" : reg }
76210037SARM gem5 Developers        eWalkCode += op
76310037SARM gem5 Developers        for reg in range(rCount):
76410037SARM gem5 Developers            eWalkCode += '''
76510037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
76610037SARM gem5 Developers        ''' % { "reg" : reg }
76710037SARM gem5 Developers        if rCount < 4:  # zero upper half
76810037SARM gem5 Developers            for reg in range(rCount, 4):
76910037SARM gem5 Developers                eWalkCode += '''
77010037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
77110037SARM gem5 Developers        ''' % { "reg" : reg }
77210037SARM gem5 Developers        iop = InstObjParams(name, Name,
77310037SARM gem5 Developers                            "DataX2RegImmOp",
77410037SARM gem5 Developers                            { "code": eWalkCode,
77510037SARM gem5 Developers                              "r_count": rCount,
77610037SARM gem5 Developers                              "op_class": opClass }, [])
77713759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
77810037SARM gem5 Developers        header_output += NeonX2RegImmOpDeclare.subst(iop)
77910037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
78010037SARM gem5 Developers        for type in types:
78110037SARM gem5 Developers            substDict = { "targs" : type,
78210037SARM gem5 Developers                          "class_name" : Name }
78310037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
78410037SARM gem5 Developers
78510037SARM gem5 Developers    def insFromGprInstX(name, Name, opClass, types, rCount, gprSpec):
78610037SARM gem5 Developers        global header_output, exec_output
78710037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
78810037SARM gem5 Developers        RegVect destReg;
78910037SARM gem5 Developers        '''
79010037SARM gem5 Developers        for reg in range(rCount):
79110037SARM gem5 Developers            eWalkCode += '''
79210037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
79310037SARM gem5 Developers        ''' % { "reg" : reg }
79410037SARM gem5 Developers        eWalkCode += '''
79510037SARM gem5 Developers        destReg.elements[imm] = htog((Element) %sOp1);
79610037SARM gem5 Developers        ''' % gprSpec
79710037SARM gem5 Developers        for reg in range(rCount):
79810037SARM gem5 Developers            eWalkCode += '''
79910037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
80010037SARM gem5 Developers        ''' % { "reg" : reg }
80110037SARM gem5 Developers        iop = InstObjParams(name, Name,
80210037SARM gem5 Developers                            "DataX1RegImmOp",
80310037SARM gem5 Developers                            { "code": eWalkCode,
80410037SARM gem5 Developers                              "r_count": rCount,
80510037SARM gem5 Developers                              "op_class": opClass }, [])
80613759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
80710037SARM gem5 Developers        header_output += NeonX1RegImmOpDeclare.subst(iop)
80810037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
80910037SARM gem5 Developers        for type in types:
81010037SARM gem5 Developers            substDict = { "targs" : type,
81110037SARM gem5 Developers                          "class_name" : Name }
81210037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
81310037SARM gem5 Developers
81410037SARM gem5 Developers    def insToGprInstX(name, Name, opClass, types, rCount, gprSpec,
81510037SARM gem5 Developers                      signExt=False):
81610037SARM gem5 Developers        global header_output, exec_output
81710037SARM gem5 Developers        eWalkCode = simd64EnabledCheckCode + '''
81810037SARM gem5 Developers        FullRegVect srcReg;
81910037SARM gem5 Developers        '''
82010037SARM gem5 Developers        for reg in range(4):
82110037SARM gem5 Developers            eWalkCode += '''
82210037SARM gem5 Developers        srcReg.regs[%(reg)d] = htog(AA64FpOp1P%(reg)d_uw);
82310037SARM gem5 Developers        ''' % { "reg" : reg }
82410037SARM gem5 Developers        if signExt:
82510037SARM gem5 Developers            eWalkCode += '''
82610037SARM gem5 Developers        %sDest = sext<sizeof(Element) * 8>(srcReg.elements[imm]);
82710037SARM gem5 Developers        ''' % gprSpec
82810037SARM gem5 Developers        else:
82910037SARM gem5 Developers            eWalkCode += '''
83010037SARM gem5 Developers        %sDest = srcReg.elements[imm];
83110037SARM gem5 Developers        ''' % gprSpec
83210037SARM gem5 Developers        iop = InstObjParams(name, Name,
83310037SARM gem5 Developers                            "DataX1RegImmOp",
83410037SARM gem5 Developers                            { "code": eWalkCode,
83510037SARM gem5 Developers                              "r_count": rCount,
83610037SARM gem5 Developers                              "op_class": opClass }, [])
83710037SARM gem5 Developers        header_output += NeonX1RegImmOpDeclare.subst(iop)
83810037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
83910037SARM gem5 Developers        for type in types:
84010037SARM gem5 Developers            substDict = { "targs" : type,
84110037SARM gem5 Developers                          "class_name" : Name }
84210037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
84310037SARM gem5 Developers
84410037SARM gem5 Developers    def tbxTblInstX(name, Name, opClass, types, length, isTbl, rCount):
84510037SARM gem5 Developers        global header_output, decoder_output, exec_output
84610037SARM gem5 Developers        code = simd64EnabledCheckCode + '''
84710037SARM gem5 Developers        union
84810037SARM gem5 Developers        {
84910037SARM gem5 Developers            uint8_t bytes[64];
85013544Sgabeblack@google.com            uint32_t regs[16];
85110037SARM gem5 Developers        } table;
85210037SARM gem5 Developers
85310037SARM gem5 Developers        union
85410037SARM gem5 Developers        {
85510037SARM gem5 Developers            uint8_t bytes[%(rCount)d * 4];
85613544Sgabeblack@google.com            uint32_t regs[%(rCount)d];
85710037SARM gem5 Developers        } destReg, srcReg2;
85810037SARM gem5 Developers
85910037SARM gem5 Developers        const unsigned length = %(length)d;
86010037SARM gem5 Developers        const bool isTbl = %(isTbl)s;
86110037SARM gem5 Developers        ''' % { "rCount" : rCount, "length" : length, "isTbl" : isTbl }
86210037SARM gem5 Developers        for reg in range(rCount):
86310037SARM gem5 Developers            code += '''
86410037SARM gem5 Developers        srcReg2.regs[%(reg)d] = htog(AA64FpOp2P%(reg)d_uw);
86510037SARM gem5 Developers        destReg.regs[%(reg)d] = htog(AA64FpDestP%(reg)d_uw);
86610037SARM gem5 Developers        ''' % { "reg" : reg }
86710037SARM gem5 Developers        for reg in range(16):
86810037SARM gem5 Developers            if reg < length * 4:
86910037SARM gem5 Developers                code += '''
87010037SARM gem5 Developers        table.regs[%(reg)d] = htog(AA64FpOp1P%(p)dV%(v)dS_uw);
87110037SARM gem5 Developers        ''' % { "reg" : reg, "p" : reg % 4, "v" : reg / 4 }
87210037SARM gem5 Developers            else:
87310037SARM gem5 Developers                code += '''
87410037SARM gem5 Developers        table.regs[%(reg)d] = 0;
87510037SARM gem5 Developers        ''' % { "reg" : reg }
87610037SARM gem5 Developers        code += '''
87710037SARM gem5 Developers        for (unsigned i = 0; i < sizeof(destReg); i++) {
87810037SARM gem5 Developers            uint8_t index = srcReg2.bytes[i];
87910037SARM gem5 Developers            if (index < 16 * length) {
88010037SARM gem5 Developers                destReg.bytes[i] = table.bytes[index];
88110037SARM gem5 Developers            } else {
88210037SARM gem5 Developers                if (isTbl)
88310037SARM gem5 Developers                    destReg.bytes[i] = 0;
88410037SARM gem5 Developers                // else destReg.bytes[i] unchanged
88510037SARM gem5 Developers            }
88610037SARM gem5 Developers        }
88710037SARM gem5 Developers        '''
88810037SARM gem5 Developers        for reg in range(rCount):
88910037SARM gem5 Developers            code += '''
89010037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]);
89110037SARM gem5 Developers        ''' % { "reg" : reg }
89210037SARM gem5 Developers        if rCount < 4:  # zero upper half
89310037SARM gem5 Developers            for reg in range(rCount, 4):
89410037SARM gem5 Developers                code += '''
89510037SARM gem5 Developers        AA64FpDestP%(reg)d_uw = 0;
89610037SARM gem5 Developers        ''' % { "reg" : reg }
89710037SARM gem5 Developers        iop = InstObjParams(name, Name,
89810037SARM gem5 Developers                            "DataX2RegOp",
89910037SARM gem5 Developers                            { "code": code,
90010037SARM gem5 Developers                              "r_count": rCount,
90110037SARM gem5 Developers                              "op_class": opClass }, [])
90213759Sgiacomo.gabrielli@arm.com        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
90310037SARM gem5 Developers        header_output += NeonX2RegOpDeclare.subst(iop)
90410037SARM gem5 Developers        exec_output += NeonXEqualRegOpExecute.subst(iop)
90510037SARM gem5 Developers        for type in types:
90610037SARM gem5 Developers            substDict = { "targs" : type,
90710037SARM gem5 Developers                          "class_name" : Name }
90810037SARM gem5 Developers            exec_output += NeonXExecDeclare.subst(substDict)
90910037SARM gem5 Developers
91010037SARM gem5 Developers    # ABS
91110037SARM gem5 Developers    absCode = '''
91210037SARM gem5 Developers            if (srcElem1 < 0) {
91310037SARM gem5 Developers                destElem = -srcElem1;
91410037SARM gem5 Developers            } else {
91510037SARM gem5 Developers                destElem = srcElem1;
91610037SARM gem5 Developers            }
91710037SARM gem5 Developers    '''
91810037SARM gem5 Developers    twoEqualRegInstX("abs", "AbsDX", "SimdAluOp", signedTypes, 2, absCode)
91910037SARM gem5 Developers    twoEqualRegInstX("abs", "AbsQX", "SimdAluOp", signedTypes, 4, absCode)
92010037SARM gem5 Developers    # ADD
92110037SARM gem5 Developers    addCode = "destElem = srcElem1 + srcElem2;"
92210037SARM gem5 Developers    threeEqualRegInstX("add", "AddDX", "SimdAddOp", unsignedTypes, 2, addCode)
92310037SARM gem5 Developers    threeEqualRegInstX("add", "AddQX", "SimdAddOp", unsignedTypes, 4, addCode)
92410037SARM gem5 Developers    # ADDHN, ADDHN2
92510037SARM gem5 Developers    addhnCode = '''
92610037SARM gem5 Developers            destElem = ((BigElement)srcElem1 + (BigElement)srcElem2) >>
92710037SARM gem5 Developers                        (sizeof(Element) * 8);
92810037SARM gem5 Developers    '''
92910037SARM gem5 Developers    threeRegNarrowInstX("addhn", "AddhnX", "SimdAddOp", smallUnsignedTypes,
93010037SARM gem5 Developers                        addhnCode)
93110037SARM gem5 Developers    threeRegNarrowInstX("addhn2", "Addhn2X", "SimdAddOp", smallUnsignedTypes,
93210037SARM gem5 Developers                        addhnCode, hi=True)
93310037SARM gem5 Developers    # ADDP (scalar)
93410037SARM gem5 Developers    twoRegPairwiseScInstX("addp", "AddpScQX", "SimdAddOp", ("uint64_t",), 4,
93510037SARM gem5 Developers                          addCode)
93610037SARM gem5 Developers    # ADDP (vector)
93710037SARM gem5 Developers    threeEqualRegInstX("addp", "AddpDX", "SimdAddOp", smallUnsignedTypes, 2,
93810037SARM gem5 Developers                       addCode, pairwise=True)
93910037SARM gem5 Developers    threeEqualRegInstX("addp", "AddpQX", "SimdAddOp", unsignedTypes, 4,
94010037SARM gem5 Developers                       addCode, pairwise=True)
94110037SARM gem5 Developers    # ADDV
94210037SARM gem5 Developers    # Note: SimdAddOp can be a bit optimistic here
94310037SARM gem5 Developers    addAcrossCode = "destElem += srcElem1;"
94410037SARM gem5 Developers    twoRegAcrossInstX("addv", "AddvDX", "SimdAddOp", ("uint8_t", "uint16_t"),
94510037SARM gem5 Developers                      2, addAcrossCode)
94610037SARM gem5 Developers    twoRegAcrossInstX("addv", "AddvQX", "SimdAddOp", smallUnsignedTypes, 4,
94710037SARM gem5 Developers                      addAcrossCode)
94810037SARM gem5 Developers    # AND
94910037SARM gem5 Developers    andCode = "destElem = srcElem1 & srcElem2;"
95010037SARM gem5 Developers    threeEqualRegInstX("and", "AndDX", "SimdAluOp", ("uint64_t",), 2, andCode)
95110037SARM gem5 Developers    threeEqualRegInstX("and", "AndQX", "SimdAluOp", ("uint64_t",), 4, andCode)
95210037SARM gem5 Developers    # BIC (immediate)
95310037SARM gem5 Developers    bicImmCode = "destElem &= ~imm;"
95410037SARM gem5 Developers    oneRegImmInstX("bic", "BicImmDX", "SimdAluOp", ("uint64_t",), 2,
95510037SARM gem5 Developers                   bicImmCode, True)
95610037SARM gem5 Developers    oneRegImmInstX("bic", "BicImmQX", "SimdAluOp", ("uint64_t",), 4,
95710037SARM gem5 Developers                   bicImmCode, True)
95810037SARM gem5 Developers    # BIC (register)
95910037SARM gem5 Developers    bicCode = "destElem = srcElem1 & ~srcElem2;"
96010037SARM gem5 Developers    threeEqualRegInstX("bic", "BicDX", "SimdAluOp", ("uint64_t",), 2, bicCode)
96110037SARM gem5 Developers    threeEqualRegInstX("bic", "BicQX", "SimdAluOp", ("uint64_t",), 4, bicCode)
96210037SARM gem5 Developers    # BIF
96310037SARM gem5 Developers    bifCode = "destElem = (destElem & srcElem2) | (srcElem1 & ~srcElem2);"
96410037SARM gem5 Developers    threeEqualRegInstX("bif", "BifDX", "SimdAluOp", ("uint64_t",), 2, bifCode,
96510037SARM gem5 Developers                       True)
96610037SARM gem5 Developers    threeEqualRegInstX("bif", "BifQX", "SimdAluOp", ("uint64_t",), 4, bifCode,
96710037SARM gem5 Developers                       True)
96810037SARM gem5 Developers    # BIT
96910037SARM gem5 Developers    bitCode = "destElem = (srcElem1 & srcElem2) | (destElem & ~srcElem2);"
97010037SARM gem5 Developers    threeEqualRegInstX("bit", "BitDX", "SimdAluOp", ("uint64_t",), 2, bitCode,
97110037SARM gem5 Developers                       True)
97210037SARM gem5 Developers    threeEqualRegInstX("bit", "BitQX", "SimdAluOp", ("uint64_t",), 4, bitCode,
97310037SARM gem5 Developers                       True)
97410037SARM gem5 Developers    # BSL
97510037SARM gem5 Developers    bslCode = "destElem = (srcElem1 & destElem) | (srcElem2 & ~destElem);"
97610037SARM gem5 Developers    threeEqualRegInstX("bsl", "BslDX", "SimdAluOp", ("uint64_t",), 2, bslCode,
97710037SARM gem5 Developers                       True)
97810037SARM gem5 Developers    threeEqualRegInstX("bsl", "BslQX", "SimdAluOp", ("uint64_t",), 4, bslCode,
97910037SARM gem5 Developers                       True)
98010037SARM gem5 Developers    # CLS
98110037SARM gem5 Developers    clsCode = '''
98210037SARM gem5 Developers            unsigned count = 0;
98310037SARM gem5 Developers            if (srcElem1 < 0) {
98410037SARM gem5 Developers                srcElem1 <<= 1;
98510037SARM gem5 Developers                while (srcElem1 < 0 && count < sizeof(Element) * 8 - 1) {
98610037SARM gem5 Developers                    count++;
98710037SARM gem5 Developers                    srcElem1 <<= 1;
98810037SARM gem5 Developers                }
98910037SARM gem5 Developers            } else {
99010037SARM gem5 Developers                srcElem1 <<= 1;
99110037SARM gem5 Developers                while (srcElem1 >= 0 && count < sizeof(Element) * 8 - 1) {
99210037SARM gem5 Developers                    count++;
99310037SARM gem5 Developers                    srcElem1 <<= 1;
99410037SARM gem5 Developers                }
99510037SARM gem5 Developers            }
99610037SARM gem5 Developers            destElem = count;
99710037SARM gem5 Developers    '''
99810037SARM gem5 Developers    twoEqualRegInstX("cls", "ClsDX", "SimdAluOp", smallSignedTypes, 2, clsCode)
99910037SARM gem5 Developers    twoEqualRegInstX("cls", "ClsQX", "SimdAluOp", smallSignedTypes, 4, clsCode)
100010037SARM gem5 Developers    # CLZ
100110037SARM gem5 Developers    clzCode = '''
100210037SARM gem5 Developers            unsigned count = 0;
100310037SARM gem5 Developers            while (srcElem1 >= 0 && count < sizeof(Element) * 8) {
100410037SARM gem5 Developers                count++;
100510037SARM gem5 Developers                srcElem1 <<= 1;
100610037SARM gem5 Developers            }
100710037SARM gem5 Developers            destElem = count;
100810037SARM gem5 Developers    '''
100910037SARM gem5 Developers    twoEqualRegInstX("clz", "ClzDX", "SimdAluOp", smallSignedTypes, 2, clzCode)
101010037SARM gem5 Developers    twoEqualRegInstX("clz", "ClzQX", "SimdAluOp", smallSignedTypes, 4, clzCode)
101110037SARM gem5 Developers    # CMEQ (register)
101210037SARM gem5 Developers    cmeqCode = "destElem = (srcElem1 == srcElem2) ? (Element)(-1) : 0;"
101310037SARM gem5 Developers    threeEqualRegInstX("cmeq", "CmeqDX", "SimdCmpOp", unsignedTypes, 2,
101410037SARM gem5 Developers                       cmeqCode)
101510037SARM gem5 Developers    threeEqualRegInstX("cmeq", "CmeqQX", "SimdCmpOp", unsignedTypes, 4,
101610037SARM gem5 Developers                       cmeqCode)
101710037SARM gem5 Developers    # CMEQ (zero)
101810037SARM gem5 Developers    cmeqZeroCode = "destElem = (srcElem1 == 0) ? (Element)(-1) : 0;"
101910037SARM gem5 Developers    twoEqualRegInstX("cmeq", "CmeqZeroDX", "SimdCmpOp", signedTypes, 2,
102010037SARM gem5 Developers                     cmeqZeroCode)
102110037SARM gem5 Developers    twoEqualRegInstX("cmeq", "CmeqZeroQX", "SimdCmpOp", signedTypes, 4,
102210037SARM gem5 Developers                     cmeqZeroCode)
102310037SARM gem5 Developers    # CMGE (register)
102410037SARM gem5 Developers    cmgeCode = "destElem = (srcElem1 >= srcElem2) ? (Element)(-1) : 0;"
102510037SARM gem5 Developers    threeEqualRegInstX("cmge", "CmgeDX", "SimdCmpOp", signedTypes, 2, cmgeCode)
102610037SARM gem5 Developers    threeEqualRegInstX("cmge", "CmgeQX", "SimdCmpOp", signedTypes, 4, cmgeCode)
102710037SARM gem5 Developers    # CMGE (zero)
102810037SARM gem5 Developers    cmgeZeroCode = "destElem = (srcElem1 >= 0) ? (Element)(-1) : 0;"
102910037SARM gem5 Developers    twoEqualRegInstX("cmge", "CmgeZeroDX", "SimdCmpOp", signedTypes, 2,
103010037SARM gem5 Developers                     cmgeZeroCode)
103110037SARM gem5 Developers    twoEqualRegInstX("cmge", "CmgeZeroQX", "SimdCmpOp", signedTypes, 4,
103210037SARM gem5 Developers                     cmgeZeroCode)
103310037SARM gem5 Developers    # CMGT (register)
103410037SARM gem5 Developers    cmgtCode = "destElem = (srcElem1 > srcElem2) ? (Element)(-1) : 0;"
103510037SARM gem5 Developers    threeEqualRegInstX("cmgt", "CmgtDX", "SimdCmpOp", signedTypes, 2, cmgtCode)
103610037SARM gem5 Developers    threeEqualRegInstX("cmgt", "CmgtQX", "SimdCmpOp", signedTypes, 4, cmgtCode)
103710037SARM gem5 Developers    # CMGT (zero)
103810037SARM gem5 Developers    cmgtZeroCode = "destElem = (srcElem1 > 0) ? (Element)(-1) : 0;"
103910037SARM gem5 Developers    twoEqualRegInstX("cmgt", "CmgtZeroDX", "SimdCmpOp", signedTypes, 2,
104010037SARM gem5 Developers                     cmgtZeroCode)
104110037SARM gem5 Developers    twoEqualRegInstX("cmgt", "CmgtZeroQX", "SimdCmpOp", signedTypes, 4,
104210037SARM gem5 Developers                     cmgtZeroCode)
104310037SARM gem5 Developers    # CMHI (register)
104410037SARM gem5 Developers    threeEqualRegInstX("cmhi", "CmhiDX", "SimdCmpOp", unsignedTypes, 2,
104510037SARM gem5 Developers                       cmgtCode)
104610037SARM gem5 Developers    threeEqualRegInstX("cmhi", "CmhiQX", "SimdCmpOp", unsignedTypes, 4,
104710037SARM gem5 Developers                       cmgtCode)
104810037SARM gem5 Developers    # CMHS (register)
104910037SARM gem5 Developers    threeEqualRegInstX("cmhs", "CmhsDX", "SimdCmpOp", unsignedTypes, 2,
105010037SARM gem5 Developers                       cmgeCode)
105110037SARM gem5 Developers    threeEqualRegInstX("cmhs", "CmhsQX", "SimdCmpOp", unsignedTypes, 4,
105210037SARM gem5 Developers                       cmgeCode)
105310037SARM gem5 Developers    # CMLE (zero)
105410037SARM gem5 Developers    cmleZeroCode = "destElem = (srcElem1 <= 0) ? (Element)(-1) : 0;"
105510037SARM gem5 Developers    twoEqualRegInstX("cmle", "CmleZeroDX", "SimdCmpOp", signedTypes, 2,
105610037SARM gem5 Developers                     cmleZeroCode)
105710037SARM gem5 Developers    twoEqualRegInstX("cmle", "CmleZeroQX", "SimdCmpOp", signedTypes, 4,
105810037SARM gem5 Developers                     cmleZeroCode)
105910037SARM gem5 Developers    # CMLT (zero)
106010037SARM gem5 Developers    cmltZeroCode = "destElem = (srcElem1 < 0) ? (Element)(-1) : 0;"
106110037SARM gem5 Developers    twoEqualRegInstX("cmlt", "CmltZeroDX", "SimdCmpOp", signedTypes, 2,
106210037SARM gem5 Developers                     cmltZeroCode)
106310037SARM gem5 Developers    twoEqualRegInstX("cmlt", "CmltZeroQX", "SimdCmpOp", signedTypes, 4,
106410037SARM gem5 Developers                     cmltZeroCode)
106510037SARM gem5 Developers    # CMTST (register)
106610037SARM gem5 Developers    tstCode = "destElem = (srcElem1 & srcElem2) ? (Element)(-1) : 0;"
106710037SARM gem5 Developers    threeEqualRegInstX("cmtst", "CmtstDX", "SimdAluOp", unsignedTypes, 2,
106810037SARM gem5 Developers                       tstCode)
106910037SARM gem5 Developers    threeEqualRegInstX("cmtst", "CmtstQX", "SimdAluOp", unsignedTypes, 4,
107010037SARM gem5 Developers                       tstCode)
107110037SARM gem5 Developers    # CNT
107210037SARM gem5 Developers    cntCode = '''
107310037SARM gem5 Developers            unsigned count = 0;
107410037SARM gem5 Developers            while (srcElem1 && count < sizeof(Element) * 8) {
107510037SARM gem5 Developers                count += srcElem1 & 0x1;
107610037SARM gem5 Developers                srcElem1 >>= 1;
107710037SARM gem5 Developers            }
107810037SARM gem5 Developers            destElem = count;
107910037SARM gem5 Developers    '''
108010037SARM gem5 Developers    twoEqualRegInstX("cnt", "CntDX", "SimdAluOp", ("uint8_t",), 2, cntCode)
108110037SARM gem5 Developers    twoEqualRegInstX("cnt", "CntQX", "SimdAluOp", ("uint8_t",), 4, cntCode)
108210037SARM gem5 Developers    # DUP (element)
108310037SARM gem5 Developers    dupCode = "destElem = srcElem1;"
108410037SARM gem5 Developers    twoEqualRegInstX("dup", "DupElemDX", "SimdMiscOp", smallUnsignedTypes, 2,
108510037SARM gem5 Developers                     dupCode, isDup=True, byElem=True)
108610037SARM gem5 Developers    twoEqualRegInstX("dup", "DupElemQX", "SimdMiscOp", unsignedTypes, 4,
108710037SARM gem5 Developers                     dupCode, isDup=True, byElem=True)
108810037SARM gem5 Developers    twoEqualRegInstX("dup", "DupElemScX", "SimdMiscOp", unsignedTypes, 4,
108910037SARM gem5 Developers                     dupCode, isDup=True, byElem=True, scalar=True)
109010037SARM gem5 Developers    # DUP (general register)
109110037SARM gem5 Developers    dupGprInstX("dup", "DupGprWDX", "SimdMiscOp", smallUnsignedTypes, 2, 'W')
109210037SARM gem5 Developers    dupGprInstX("dup", "DupGprWQX", "SimdMiscOp", smallUnsignedTypes, 4, 'W')
109310037SARM gem5 Developers    dupGprInstX("dup", "DupGprXQX", "SimdMiscOp", ("uint64_t",), 4, 'X')
109410037SARM gem5 Developers    # EOR
109510037SARM gem5 Developers    eorCode = "destElem = srcElem1 ^ srcElem2;"
109610037SARM gem5 Developers    threeEqualRegInstX("eor", "EorDX", "SimdAluOp", ("uint64_t",), 2, eorCode)
109710037SARM gem5 Developers    threeEqualRegInstX("eor", "EorQX", "SimdAluOp", ("uint64_t",), 4, eorCode)
109810037SARM gem5 Developers    # EXT
109910037SARM gem5 Developers    extCode = '''
110010037SARM gem5 Developers            for (unsigned i = 0; i < eCount; i++) {
110110037SARM gem5 Developers                unsigned index = i + imm;
110210037SARM gem5 Developers                if (index < eCount) {
110310037SARM gem5 Developers                    destReg.elements[i] = srcReg1.elements[index];
110410037SARM gem5 Developers                } else {
110510037SARM gem5 Developers                    index -= eCount;
110610037SARM gem5 Developers                    if (index >= eCount) {
110710474Sandreas.hansson@arm.com                        fault = std::make_shared<UndefinedInstruction>(
110810474Sandreas.hansson@arm.com                                      machInst, false, mnemonic);
110910037SARM gem5 Developers                    } else {
111010037SARM gem5 Developers                        destReg.elements[i] = srcReg2.elements[index];
111110037SARM gem5 Developers                    }
111210037SARM gem5 Developers                }
111310037SARM gem5 Developers            }
111410037SARM gem5 Developers    '''
111510037SARM gem5 Developers    extInstX("Ext", "ExtDX", "SimdMiscOp", ("uint8_t",), 2, extCode)
111610037SARM gem5 Developers    extInstX("Ext", "ExtQX", "SimdMiscOp", ("uint8_t",), 4, extCode)
111710037SARM gem5 Developers    # FABD
111810037SARM gem5 Developers    fpOp = '''
111910037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrExc;
112010037SARM gem5 Developers            destElem = %s;
112110037SARM gem5 Developers            FpscrExc = fpscr;
112210037SARM gem5 Developers    '''
112310037SARM gem5 Developers    fabdCode = fpOp % "fplibAbs<Element>(fplibSub(srcElem1, srcElem2, fpscr))"
112410037SARM gem5 Developers    threeEqualRegInstX("fabd", "FabdDX", "SimdFloatAddOp", smallFloatTypes, 2,
112510037SARM gem5 Developers                       fabdCode)
112610037SARM gem5 Developers    threeEqualRegInstX("fabd", "FabdQX", "SimdFloatAddOp", floatTypes, 4,
112710037SARM gem5 Developers                       fabdCode)
112810037SARM gem5 Developers    threeEqualRegInstX("fabd", "FabdScX", "SimdFloatAddOp", floatTypes, 4,
112910037SARM gem5 Developers                       fabdCode, scalar=True)
113010037SARM gem5 Developers    # FABS
113110037SARM gem5 Developers    fabsCode = fpOp % "fplibAbs<Element>(srcElem1)"
113210037SARM gem5 Developers    twoEqualRegInstX("Abs", "FabsDX", "SimdFloatAluOp", smallFloatTypes, 2,
113310037SARM gem5 Developers                     fabsCode)
113410037SARM gem5 Developers    twoEqualRegInstX("Abs", "FabsQX", "SimdFloatAluOp", floatTypes, 4,
113510037SARM gem5 Developers                     fabsCode)
113610037SARM gem5 Developers    # FACGE
113710037SARM gem5 Developers    fpCmpAbsOp = fpOp % ("fplibCompare%s<Element>(fplibAbs<Element>(srcElem1),"
113810037SARM gem5 Developers                         " fplibAbs<Element>(srcElem2), fpscr) ? -1 : 0")
113910037SARM gem5 Developers    facgeCode = fpCmpAbsOp % "GE"
114010037SARM gem5 Developers    threeEqualRegInstX("facge", "FacgeDX", "SimdFloatCmpOp", smallFloatTypes,
114110037SARM gem5 Developers                       2, facgeCode)
114210037SARM gem5 Developers    threeEqualRegInstX("facge", "FacgeQX", "SimdFloatCmpOp", floatTypes, 4,
114310037SARM gem5 Developers                       facgeCode)
114410037SARM gem5 Developers    threeEqualRegInstX("facge", "FacgeScX", "SimdFloatCmpOp", floatTypes, 4,
114510037SARM gem5 Developers                       facgeCode, scalar=True)
114610037SARM gem5 Developers    # FACGT
114710037SARM gem5 Developers    facgtCode = fpCmpAbsOp % "GT"
114810037SARM gem5 Developers    threeEqualRegInstX("facgt", "FacgtDX", "SimdFloatCmpOp", smallFloatTypes,
114910037SARM gem5 Developers                       2, facgtCode)
115010037SARM gem5 Developers    threeEqualRegInstX("facgt", "FacgtQX", "SimdFloatCmpOp", floatTypes, 4,
115110037SARM gem5 Developers                       facgtCode)
115210037SARM gem5 Developers    threeEqualRegInstX("facgt", "FacgtScX", "SimdFloatCmpOp", floatTypes, 4,
115310037SARM gem5 Developers                       facgtCode, scalar=True)
115410037SARM gem5 Developers    # FADD
115510037SARM gem5 Developers    fpBinOp = fpOp % "fplib%s<Element>(srcElem1, srcElem2, fpscr)"
115610037SARM gem5 Developers    faddCode = fpBinOp % "Add"
115710037SARM gem5 Developers    threeEqualRegInstX("fadd", "FaddDX", "SimdFloatAddOp", smallFloatTypes, 2,
115810037SARM gem5 Developers                       faddCode)
115910037SARM gem5 Developers    threeEqualRegInstX("fadd", "FaddQX", "SimdFloatAddOp", floatTypes, 4,
116010037SARM gem5 Developers                       faddCode)
116110037SARM gem5 Developers    # FADDP (scalar)
116210037SARM gem5 Developers    twoRegPairwiseScInstX("faddp", "FaddpScDX", "SimdFloatAddOp",
116310037SARM gem5 Developers                          ("uint32_t",), 2, faddCode)
116410037SARM gem5 Developers    twoRegPairwiseScInstX("faddp", "FaddpScQX", "SimdFloatAddOp",
116510037SARM gem5 Developers                          ("uint64_t",), 4, faddCode)
116610037SARM gem5 Developers    # FADDP (vector)
116710037SARM gem5 Developers    threeEqualRegInstX("faddp", "FaddpDX", "SimdFloatAddOp", smallFloatTypes,
116810037SARM gem5 Developers                       2, faddCode, pairwise=True)
116910037SARM gem5 Developers    threeEqualRegInstX("faddp", "FaddpQX", "SimdFloatAddOp", floatTypes, 4,
117010037SARM gem5 Developers                       faddCode, pairwise=True)
117110037SARM gem5 Developers    # FCMEQ (register)
117210037SARM gem5 Developers    fpCmpOp = fpOp % ("fplibCompare%s<Element>(srcElem1, srcElem2, fpscr) ?"
117310037SARM gem5 Developers                      " -1 : 0")
117410037SARM gem5 Developers    fcmeqCode = fpCmpOp % "EQ"
117510037SARM gem5 Developers    threeEqualRegInstX("fcmeq", "FcmeqDX", "SimdFloatCmpOp", smallFloatTypes,
117610037SARM gem5 Developers                       2, fcmeqCode)
117710037SARM gem5 Developers    threeEqualRegInstX("fcmeq", "FcmeqQX", "SimdFloatCmpOp", floatTypes, 4,
117810037SARM gem5 Developers                       fcmeqCode)
117910037SARM gem5 Developers    threeEqualRegInstX("fcmeq", "FcmeqScX", "SimdFloatCmpOp", floatTypes, 4,
118010037SARM gem5 Developers                       fcmeqCode, scalar=True)
118110037SARM gem5 Developers    # FCMEQ (zero)
118210037SARM gem5 Developers    fpCmpZeroOp = fpOp % "fplibCompare%s<Element>(srcElem1, 0, fpscr) ? -1 : 0"
118310037SARM gem5 Developers    fcmeqZeroCode = fpCmpZeroOp % "EQ"
118410037SARM gem5 Developers    twoEqualRegInstX("fcmeq", "FcmeqZeroDX", "SimdFloatCmpOp", smallFloatTypes,
118510037SARM gem5 Developers                     2, fcmeqZeroCode)
118610037SARM gem5 Developers    twoEqualRegInstX("fcmeq", "FcmeqZeroQX", "SimdFloatCmpOp", floatTypes, 4,
118710037SARM gem5 Developers                     fcmeqZeroCode)
118810037SARM gem5 Developers    twoEqualRegInstX("fcmeq", "FcmeqZeroScX", "SimdFloatCmpOp", floatTypes, 4,
118910037SARM gem5 Developers                     fcmeqZeroCode, scalar=True)
119010037SARM gem5 Developers    # FCMGE (register)
119110037SARM gem5 Developers    fcmgeCode = fpCmpOp % "GE"
119210037SARM gem5 Developers    threeEqualRegInstX("fcmge", "FcmgeDX", "SimdFloatCmpOp", smallFloatTypes,
119310037SARM gem5 Developers                       2, fcmgeCode)
119410037SARM gem5 Developers    threeEqualRegInstX("fcmge", "FcmgeQX", "SimdFloatCmpOp", floatTypes, 4,
119510037SARM gem5 Developers                       fcmgeCode)
119610037SARM gem5 Developers    threeEqualRegInstX("fcmge", "FcmgeScX", "SimdFloatCmpOp", floatTypes, 4,
119710037SARM gem5 Developers                       fcmgeCode, scalar=True)
119810037SARM gem5 Developers    # FCMGE (zero)
119910037SARM gem5 Developers    fcmgeZeroCode = fpCmpZeroOp % "GE"
120010037SARM gem5 Developers    twoEqualRegInstX("fcmge", "FcmgeZeroDX", "SimdFloatCmpOp", smallFloatTypes,
120110037SARM gem5 Developers                     2, fcmgeZeroCode)
120210037SARM gem5 Developers    twoEqualRegInstX("fcmge", "FcmgeZeroQX", "SimdFloatCmpOp", floatTypes, 4,
120310037SARM gem5 Developers                     fcmgeZeroCode)
120410037SARM gem5 Developers    twoEqualRegInstX("fcmge", "FcmgeZeroScX", "SimdFloatCmpOp", floatTypes, 4,
120510037SARM gem5 Developers                     fcmgeZeroCode, scalar=True)
120610037SARM gem5 Developers    # FCMGT (register)
120710037SARM gem5 Developers    fcmgtCode = fpCmpOp % "GT"
120810037SARM gem5 Developers    threeEqualRegInstX("fcmgt", "FcmgtDX", "SimdFloatCmpOp", smallFloatTypes,
120910037SARM gem5 Developers                       2, fcmgtCode)
121010037SARM gem5 Developers    threeEqualRegInstX("fcmgt", "FcmgtQX", "SimdFloatCmpOp", floatTypes, 4,
121110037SARM gem5 Developers                       fcmgtCode)
121210037SARM gem5 Developers    threeEqualRegInstX("fcmgt", "FcmgtScX", "SimdFloatCmpOp", floatTypes, 4,
121310037SARM gem5 Developers                       fcmgtCode, scalar=True)
121410037SARM gem5 Developers    # FCMGT (zero)
121510037SARM gem5 Developers    fcmgtZeroCode = fpCmpZeroOp % "GT"
121610037SARM gem5 Developers    twoEqualRegInstX("fcmgt", "FcmgtZeroDX", "SimdFloatCmpOp", smallFloatTypes,
121710037SARM gem5 Developers                     2, fcmgtZeroCode)
121810037SARM gem5 Developers    twoEqualRegInstX("fcmgt", "FcmgtZeroQX", "SimdFloatCmpOp", floatTypes, 4,
121910037SARM gem5 Developers                     fcmgtZeroCode)
122010037SARM gem5 Developers    twoEqualRegInstX("fcmgt", "FcmgtZeroScX", "SimdFloatCmpOp", floatTypes, 4,
122110037SARM gem5 Developers                     fcmgtZeroCode, scalar=True)
122210037SARM gem5 Developers    # FCMLE (zero)
122310037SARM gem5 Developers    fpCmpRevZeroOp = fpOp % ("fplibCompare%s<Element>(0, srcElem1, fpscr) ?"
122410037SARM gem5 Developers                             " -1 : 0")
122510037SARM gem5 Developers    fcmleZeroCode = fpCmpRevZeroOp % "GE"
122610037SARM gem5 Developers    twoEqualRegInstX("fcmle", "FcmleZeroDX", "SimdFloatCmpOp", smallFloatTypes,
122710037SARM gem5 Developers                     2, fcmleZeroCode)
122810037SARM gem5 Developers    twoEqualRegInstX("fcmle", "FcmleZeroQX", "SimdFloatCmpOp", floatTypes, 4,
122910037SARM gem5 Developers                     fcmleZeroCode)
123010037SARM gem5 Developers    twoEqualRegInstX("fcmle", "FcmleZeroScX", "SimdFloatCmpOp", floatTypes, 4,
123110037SARM gem5 Developers                     fcmleZeroCode, scalar=True)
123210037SARM gem5 Developers    # FCMLT (zero)
123310037SARM gem5 Developers    fcmltZeroCode = fpCmpRevZeroOp % "GT"
123410037SARM gem5 Developers    twoEqualRegInstX("fcmlt", "FcmltZeroDX", "SimdFloatCmpOp", smallFloatTypes,
123510037SARM gem5 Developers                     2, fcmltZeroCode)
123610037SARM gem5 Developers    twoEqualRegInstX("fcmlt", "FcmltZeroQX", "SimdFloatCmpOp", floatTypes, 4,
123710037SARM gem5 Developers                     fcmltZeroCode)
123810037SARM gem5 Developers    twoEqualRegInstX("fcmlt", "FcmltZeroScX", "SimdFloatCmpOp", floatTypes, 4,
123910037SARM gem5 Developers                     fcmltZeroCode, scalar=True)
124010037SARM gem5 Developers    # FCVTAS
124110037SARM gem5 Developers    fcvtCode = fpOp % ("fplibFPToFixed<Element, Element>("
124210037SARM gem5 Developers                       "srcElem1, %s, %s, %s, fpscr)")
124310037SARM gem5 Developers    fcvtasCode = fcvtCode % ("0", "false", "FPRounding_TIEAWAY")
124410037SARM gem5 Developers    twoEqualRegInstX("fcvtas", "FcvtasDX", "SimdCvtOp", smallFloatTypes, 2,
124510037SARM gem5 Developers                     fcvtasCode)
124610037SARM gem5 Developers    twoEqualRegInstX("fcvtas", "FcvtasQX", "SimdCvtOp", floatTypes, 4,
124710037SARM gem5 Developers                     fcvtasCode)
124810037SARM gem5 Developers    twoEqualRegInstX("fcvtas", "FcvtasScX", "SimdCvtOp", floatTypes, 4,
124910037SARM gem5 Developers                     fcvtasCode, scalar=True)
125010037SARM gem5 Developers    # FCVTAU
125110037SARM gem5 Developers    fcvtauCode = fcvtCode % ("0", "true", "FPRounding_TIEAWAY")
125210037SARM gem5 Developers    twoEqualRegInstX("fcvtau", "FcvtauDX", "SimdCvtOp", smallFloatTypes, 2,
125310037SARM gem5 Developers                     fcvtauCode)
125410037SARM gem5 Developers    twoEqualRegInstX("fcvtau", "FcvtauQX", "SimdCvtOp", floatTypes, 4,
125510037SARM gem5 Developers                     fcvtauCode)
125610037SARM gem5 Developers    twoEqualRegInstX("fcvtau", "FcvtauScX", "SimdCvtOp", floatTypes, 4,
125710037SARM gem5 Developers                     fcvtauCode, scalar=True)
125810037SARM gem5 Developers    # FCVTL, FCVTL2
125910037SARM gem5 Developers    fcvtlCode = fpOp % ("fplibConvert<Element, BigElement>("
126010037SARM gem5 Developers                        "srcElem1, FPCRRounding(fpscr), fpscr)")
126110037SARM gem5 Developers    twoRegLongInstX("fcvtl", "FcvtlX", "SimdCvtOp", ("uint16_t", "uint32_t"),
126210037SARM gem5 Developers                    fcvtlCode)
126310037SARM gem5 Developers    twoRegLongInstX("fcvtl", "Fcvtl2X", "SimdCvtOp", ("uint16_t", "uint32_t"),
126410037SARM gem5 Developers                    fcvtlCode, hi=True)
126510037SARM gem5 Developers    # FCVTMS
126610037SARM gem5 Developers    fcvtmsCode = fcvtCode % ("0", "false", "FPRounding_NEGINF")
126710037SARM gem5 Developers    twoEqualRegInstX("fcvtms", "FcvtmsDX", "SimdCvtOp", smallFloatTypes, 2,
126810037SARM gem5 Developers                     fcvtmsCode)
126910037SARM gem5 Developers    twoEqualRegInstX("fcvtms", "FcvtmsQX", "SimdCvtOp", floatTypes, 4,
127010037SARM gem5 Developers                     fcvtmsCode)
127110037SARM gem5 Developers    twoEqualRegInstX("fcvtms", "FcvtmsScX", "SimdCvtOp", floatTypes, 4,
127210037SARM gem5 Developers                     fcvtmsCode, scalar=True)
127310037SARM gem5 Developers    # FCVTMU
127410037SARM gem5 Developers    fcvtmuCode = fcvtCode % ("0", "true", "FPRounding_NEGINF")
127510037SARM gem5 Developers    twoEqualRegInstX("fcvtmu", "FcvtmuDX", "SimdCvtOp", smallFloatTypes, 2,
127610037SARM gem5 Developers                     fcvtmuCode)
127710037SARM gem5 Developers    twoEqualRegInstX("fcvtmu", "FcvtmuQX", "SimdCvtOp", floatTypes, 4,
127810037SARM gem5 Developers                     fcvtmuCode)
127910037SARM gem5 Developers    twoEqualRegInstX("fcvtmu", "FcvtmuScX", "SimdCvtOp", floatTypes, 4,
128010037SARM gem5 Developers                     fcvtmuCode, scalar=True)
128110037SARM gem5 Developers    # FCVTN, FCVTN2
128210037SARM gem5 Developers    fcvtnCode = fpOp % ("fplibConvert<BigElement, Element>("
128310037SARM gem5 Developers                        "srcElem1, FPCRRounding(fpscr), fpscr)")
128410037SARM gem5 Developers    twoRegNarrowInstX("fcvtn", "FcvtnX", "SimdCvtOp",
128510037SARM gem5 Developers                      ("uint16_t", "uint32_t"), fcvtnCode)
128610037SARM gem5 Developers    twoRegNarrowInstX("fcvtn", "Fcvtn2X", "SimdCvtOp",
128710037SARM gem5 Developers                      ("uint16_t", "uint32_t"), fcvtnCode, hi=True)
128810037SARM gem5 Developers    # FCVTNS
128910037SARM gem5 Developers    fcvtnsCode = fcvtCode % ("0", "false", "FPRounding_TIEEVEN")
129010037SARM gem5 Developers    twoEqualRegInstX("fcvtns", "FcvtnsDX", "SimdCvtOp", smallFloatTypes, 2,
129110037SARM gem5 Developers                     fcvtnsCode)
129210037SARM gem5 Developers    twoEqualRegInstX("fcvtns", "FcvtnsQX", "SimdCvtOp", floatTypes, 4,
129310037SARM gem5 Developers                     fcvtnsCode)
129410037SARM gem5 Developers    twoEqualRegInstX("fcvtns", "FcvtnsScX", "SimdCvtOp", floatTypes, 4,
129510037SARM gem5 Developers                     fcvtnsCode, scalar=True)
129610037SARM gem5 Developers    # FCVTNU
129710037SARM gem5 Developers    fcvtnuCode = fcvtCode % ("0", "true", "FPRounding_TIEEVEN")
129810037SARM gem5 Developers    twoEqualRegInstX("fcvtnu", "FcvtnuDX", "SimdCvtOp", smallFloatTypes, 2,
129910037SARM gem5 Developers                     fcvtnuCode)
130010037SARM gem5 Developers    twoEqualRegInstX("fcvtnu", "FcvtnuQX", "SimdCvtOp", floatTypes, 4,
130110037SARM gem5 Developers                     fcvtnuCode)
130210037SARM gem5 Developers    twoEqualRegInstX("fcvtnu", "FcvtnuScX", "SimdCvtOp", floatTypes, 4,
130310037SARM gem5 Developers                     fcvtnuCode, scalar=True)
130410037SARM gem5 Developers    # FCVTPS
130510037SARM gem5 Developers    fcvtpsCode = fcvtCode % ("0", "false", "FPRounding_POSINF")
130610037SARM gem5 Developers    twoEqualRegInstX("fcvtps", "FcvtpsDX", "SimdCvtOp", smallFloatTypes, 2,
130710037SARM gem5 Developers                     fcvtpsCode)
130810037SARM gem5 Developers    twoEqualRegInstX("fcvtps", "FcvtpsQX", "SimdCvtOp", floatTypes, 4,
130910037SARM gem5 Developers                     fcvtpsCode)
131010037SARM gem5 Developers    twoEqualRegInstX("fcvtps", "FcvtpsScX", "SimdCvtOp", floatTypes, 4,
131110037SARM gem5 Developers                     fcvtpsCode, scalar=True)
131210037SARM gem5 Developers    # FCVTPU
131310037SARM gem5 Developers    fcvtpuCode = fcvtCode % ("0", "true", "FPRounding_POSINF")
131410037SARM gem5 Developers    twoEqualRegInstX("fcvtpu", "FcvtpuDX", "SimdCvtOp", smallFloatTypes, 2,
131510037SARM gem5 Developers                     fcvtpuCode)
131610037SARM gem5 Developers    twoEqualRegInstX("fcvtpu", "FcvtpuQX", "SimdCvtOp", floatTypes, 4,
131710037SARM gem5 Developers                     fcvtpuCode)
131810037SARM gem5 Developers    twoEqualRegInstX("fcvtpu", "FcvtpuScX", "SimdCvtOp", floatTypes, 4,
131910037SARM gem5 Developers                     fcvtpuCode, scalar=True)
132010037SARM gem5 Developers    # FCVTXN, FCVTXN2
132110037SARM gem5 Developers    fcvtxnCode = fpOp % ("fplibConvert<BigElement, Element>("
132210037SARM gem5 Developers                         "srcElem1, FPRounding_ODD, fpscr)")
132310037SARM gem5 Developers    twoRegNarrowInstX("fcvtxn", "FcvtxnX", "SimdCvtOp", smallFloatTypes,
132410037SARM gem5 Developers                      fcvtxnCode)
132510037SARM gem5 Developers    twoRegNarrowInstX("fcvtxn", "Fcvtxn2X", "SimdCvtOp", smallFloatTypes,
132610037SARM gem5 Developers                      fcvtxnCode, hi=True)
132710037SARM gem5 Developers    twoRegNarrowInstX("fcvtxn", "FcvtxnScX", "SimdCvtOp", smallFloatTypes,
132810037SARM gem5 Developers                      fcvtxnCode, scalar=True)
132910037SARM gem5 Developers    # FCVTZS (fixed-point)
133010037SARM gem5 Developers    fcvtzsCode = fcvtCode % ("imm", "false", "FPRounding_ZERO")
133110037SARM gem5 Developers    twoEqualRegInstX("fcvtzs", "FcvtzsFixedDX", "SimdCvtOp", smallFloatTypes,
133210037SARM gem5 Developers                     2, fcvtzsCode, hasImm=True)
133310037SARM gem5 Developers    twoEqualRegInstX("fcvtzs", "FcvtzsFixedQX", "SimdCvtOp", floatTypes, 4,
133410037SARM gem5 Developers                     fcvtzsCode, hasImm=True)
133510037SARM gem5 Developers    twoEqualRegInstX("fcvtzs", "FcvtzsFixedScX", "SimdCvtOp", floatTypes, 4,
133610037SARM gem5 Developers                     fcvtzsCode, hasImm=True, scalar=True)
133710037SARM gem5 Developers    # FCVTZS (integer)
133810037SARM gem5 Developers    fcvtzsIntCode = fcvtCode % ("0", "false", "FPRounding_ZERO")
133910037SARM gem5 Developers    twoEqualRegInstX("fcvtzs", "FcvtzsIntDX", "SimdCvtOp", smallFloatTypes,
134010037SARM gem5 Developers                     2, fcvtzsIntCode)
134110037SARM gem5 Developers    twoEqualRegInstX("fcvtzs", "FcvtzsIntQX", "SimdCvtOp", floatTypes, 4,
134210037SARM gem5 Developers                     fcvtzsIntCode)
134310037SARM gem5 Developers    twoEqualRegInstX("fcvtzs", "FcvtzsIntScX", "SimdCvtOp", floatTypes, 4,
134410037SARM gem5 Developers                     fcvtzsIntCode, scalar=True)
134510037SARM gem5 Developers    # FCVTZU (fixed-point)
134610037SARM gem5 Developers    fcvtzuCode = fcvtCode % ("imm", "true", "FPRounding_ZERO")
134710037SARM gem5 Developers    twoEqualRegInstX("fcvtzu", "FcvtzuFixedDX", "SimdCvtOp", smallFloatTypes,
134810037SARM gem5 Developers                     2, fcvtzuCode, hasImm=True)
134910037SARM gem5 Developers    twoEqualRegInstX("fcvtzu", "FcvtzuFixedQX", "SimdCvtOp", floatTypes, 4,
135010037SARM gem5 Developers                     fcvtzuCode, hasImm=True)
135110037SARM gem5 Developers    twoEqualRegInstX("fcvtzu", "FcvtzuFixedScX", "SimdCvtOp", floatTypes, 4,
135210037SARM gem5 Developers                     fcvtzuCode, hasImm=True, scalar=True)
135310037SARM gem5 Developers    # FCVTZU (integer)
135410037SARM gem5 Developers    fcvtzuIntCode = fcvtCode % ("0", "true", "FPRounding_ZERO")
135510037SARM gem5 Developers    twoEqualRegInstX("fcvtzu", "FcvtzuIntDX", "SimdCvtOp", smallFloatTypes, 2,
135610037SARM gem5 Developers                     fcvtzuIntCode)
135710037SARM gem5 Developers    twoEqualRegInstX("fcvtzu", "FcvtzuIntQX", "SimdCvtOp", floatTypes, 4,
135810037SARM gem5 Developers                     fcvtzuIntCode)
135910037SARM gem5 Developers    twoEqualRegInstX("fcvtzu", "FcvtzuIntScX", "SimdCvtOp", floatTypes, 4,
136010037SARM gem5 Developers                     fcvtzuIntCode, scalar=True)
136110037SARM gem5 Developers    # FDIV
136210037SARM gem5 Developers    fdivCode = fpBinOp % "Div"
136310037SARM gem5 Developers    threeEqualRegInstX("fdiv", "FdivDX", "SimdFloatDivOp", smallFloatTypes, 2,
136410037SARM gem5 Developers                       fdivCode)
136510037SARM gem5 Developers    threeEqualRegInstX("fdiv", "FdivQX", "SimdFloatDivOp", floatTypes, 4,
136610037SARM gem5 Developers                       fdivCode)
136710037SARM gem5 Developers    # FMAX
136810037SARM gem5 Developers    fmaxCode = fpBinOp % "Max"
136910037SARM gem5 Developers    threeEqualRegInstX("fmax", "FmaxDX", "SimdFloatCmpOp", smallFloatTypes, 2,
137010037SARM gem5 Developers                       fmaxCode)
137110037SARM gem5 Developers    threeEqualRegInstX("fmax", "FmaxQX", "SimdFloatCmpOp", floatTypes, 4,
137210037SARM gem5 Developers                       fmaxCode)
137310037SARM gem5 Developers    # FMAXNM
137410037SARM gem5 Developers    fmaxnmCode = fpBinOp % "MaxNum"
137510037SARM gem5 Developers    threeEqualRegInstX("fmaxnm", "FmaxnmDX", "SimdFloatCmpOp", smallFloatTypes,
137610037SARM gem5 Developers                       2, fmaxnmCode)
137710037SARM gem5 Developers    threeEqualRegInstX("fmaxnm", "FmaxnmQX", "SimdFloatCmpOp", floatTypes, 4,
137810037SARM gem5 Developers                       fmaxnmCode)
137910037SARM gem5 Developers    # FMAXNMP (scalar)
138010037SARM gem5 Developers    twoRegPairwiseScInstX("fmaxnmp", "FmaxnmpScDX", "SimdFloatCmpOp",
138110037SARM gem5 Developers                          ("uint32_t",), 2, fmaxnmCode)
138210037SARM gem5 Developers    twoRegPairwiseScInstX("fmaxnmp", "FmaxnmpScQX", "SimdFloatCmpOp",
138310037SARM gem5 Developers                          ("uint64_t",), 4, fmaxnmCode)
138410037SARM gem5 Developers    # FMAXNMP (vector)
138510037SARM gem5 Developers    threeEqualRegInstX("fmaxnmp", "FmaxnmpDX", "SimdFloatCmpOp",
138610037SARM gem5 Developers                       smallFloatTypes, 2, fmaxnmCode, pairwise=True)
138710037SARM gem5 Developers    threeEqualRegInstX("fmaxnmp", "FmaxnmpQX", "SimdFloatCmpOp", floatTypes, 4,
138810037SARM gem5 Developers                       fmaxnmCode, pairwise=True)
138910037SARM gem5 Developers    # FMAXNMV
139010037SARM gem5 Developers    # Note: SimdFloatCmpOp can be a bit optimistic here
139110037SARM gem5 Developers    fpAcrossOp = fpOp % "fplib%s<Element>(destElem, srcElem1, fpscr)"
139210037SARM gem5 Developers    fmaxnmAcrossCode = fpAcrossOp % "MaxNum"
139310037SARM gem5 Developers    twoRegAcrossInstX("fmaxnmv", "FmaxnmvQX", "SimdFloatCmpOp", ("uint32_t",),
139410037SARM gem5 Developers                      4, fmaxnmAcrossCode)
139510037SARM gem5 Developers    # FMAXP (scalar)
139610037SARM gem5 Developers    twoRegPairwiseScInstX("fmaxp", "FmaxpScDX", "SimdFloatCmpOp",
139710037SARM gem5 Developers                          ("uint32_t",), 2, fmaxCode)
139810037SARM gem5 Developers    twoRegPairwiseScInstX("fmaxp", "FmaxpScQX", "SimdFloatCmpOp",
139910037SARM gem5 Developers                          ("uint64_t",), 4, fmaxCode)
140010037SARM gem5 Developers    # FMAXP (vector)
140110037SARM gem5 Developers    threeEqualRegInstX("fmaxp", "FmaxpDX", "SimdFloatCmpOp", smallFloatTypes,
140210037SARM gem5 Developers                       2, fmaxCode, pairwise=True)
140310037SARM gem5 Developers    threeEqualRegInstX("fmaxp", "FmaxpQX", "SimdFloatCmpOp", floatTypes, 4,
140410037SARM gem5 Developers                       fmaxCode, pairwise=True)
140510037SARM gem5 Developers    # FMAXV
140610037SARM gem5 Developers    # Note: SimdFloatCmpOp can be a bit optimistic here
140710037SARM gem5 Developers    fmaxAcrossCode = fpAcrossOp % "Max"
140810037SARM gem5 Developers    twoRegAcrossInstX("fmaxv", "FmaxvQX", "SimdFloatCmpOp", ("uint32_t",), 4,
140910037SARM gem5 Developers                      fmaxAcrossCode)
141010037SARM gem5 Developers    # FMIN
141110037SARM gem5 Developers    fminCode = fpBinOp % "Min"
141210037SARM gem5 Developers    threeEqualRegInstX("fmin", "FminDX", "SimdFloatCmpOp", smallFloatTypes, 2,
141310037SARM gem5 Developers                       fminCode)
141410037SARM gem5 Developers    threeEqualRegInstX("fmin", "FminQX", "SimdFloatCmpOp", floatTypes, 4,
141510037SARM gem5 Developers                       fminCode)
141610037SARM gem5 Developers    # FMINNM
141710037SARM gem5 Developers    fminnmCode = fpBinOp % "MinNum"
141810037SARM gem5 Developers    threeEqualRegInstX("fminnm", "FminnmDX", "SimdFloatCmpOp", smallFloatTypes,
141910037SARM gem5 Developers                       2, fminnmCode)
142010037SARM gem5 Developers    threeEqualRegInstX("fminnm", "FminnmQX", "SimdFloatCmpOp", floatTypes, 4,
142110037SARM gem5 Developers                       fminnmCode)
142210037SARM gem5 Developers    # FMINNMP (scalar)
142310037SARM gem5 Developers    twoRegPairwiseScInstX("fminnmp", "FminnmpScDX", "SimdFloatCmpOp",
142410037SARM gem5 Developers                          ("uint32_t",), 2, fminnmCode)
142510037SARM gem5 Developers    twoRegPairwiseScInstX("fminnmp", "FminnmpScQX", "SimdFloatCmpOp",
142610037SARM gem5 Developers                          ("uint64_t",), 4, fminnmCode)
142710037SARM gem5 Developers    # FMINNMP (vector)
142810037SARM gem5 Developers    threeEqualRegInstX("fminnmp", "FminnmpDX", "SimdFloatCmpOp",
142910037SARM gem5 Developers                       smallFloatTypes, 2, fminnmCode, pairwise=True)
143010037SARM gem5 Developers    threeEqualRegInstX("fminnmp", "FminnmpQX", "SimdFloatCmpOp", floatTypes, 4,
143110037SARM gem5 Developers                       fminnmCode, pairwise=True)
143210037SARM gem5 Developers    # FMINNMV
143310037SARM gem5 Developers    # Note: SimdFloatCmpOp can be a bit optimistic here
143410037SARM gem5 Developers    fminnmAcrossCode = fpAcrossOp % "MinNum"
143510037SARM gem5 Developers    twoRegAcrossInstX("fminnmv", "FminnmvQX", "SimdFloatCmpOp", ("uint32_t",),
143610037SARM gem5 Developers                      4, fminnmAcrossCode)
143710037SARM gem5 Developers    # FMINP (scalar)
143810037SARM gem5 Developers    twoRegPairwiseScInstX("fminp", "FminpScDX", "SimdFloatCmpOp",
143910037SARM gem5 Developers                          ("uint32_t",), 2, fminCode)
144010037SARM gem5 Developers    twoRegPairwiseScInstX("fminp", "FminpScQX", "SimdFloatCmpOp",
144110037SARM gem5 Developers                          ("uint64_t",), 4, fminCode)
144210037SARM gem5 Developers    # FMINP (vector)
144310037SARM gem5 Developers    threeEqualRegInstX("fminp", "FminpDX", "SimdFloatCmpOp", smallFloatTypes,
144410037SARM gem5 Developers                       2, fminCode, pairwise=True)
144510037SARM gem5 Developers    threeEqualRegInstX("fminp", "FminpQX", "SimdFloatCmpOp", floatTypes, 4,
144610037SARM gem5 Developers                       fminCode, pairwise=True)
144710037SARM gem5 Developers    # FMINV
144810037SARM gem5 Developers    # Note: SimdFloatCmpOp can be a bit optimistic here
144910037SARM gem5 Developers    fminAcrossCode = fpAcrossOp % "Min"
145010037SARM gem5 Developers    twoRegAcrossInstX("fminv", "FminvQX", "SimdFloatCmpOp", ("uint32_t",), 4,
145110037SARM gem5 Developers                      fminAcrossCode)
145210037SARM gem5 Developers    # FMLA (by element)
145310037SARM gem5 Developers    fmlaCode = fpOp % ("fplibMulAdd<Element>("
145410037SARM gem5 Developers                       "destElem, srcElem1, srcElem2, fpscr)")
145510037SARM gem5 Developers    threeEqualRegInstX("fmla", "FmlaElemDX", "SimdFloatMultAccOp",
145610037SARM gem5 Developers                       smallFloatTypes, 2, fmlaCode, True, byElem=True)
145710037SARM gem5 Developers    threeEqualRegInstX("fmla", "FmlaElemQX", "SimdFloatMultAccOp", floatTypes,
145810037SARM gem5 Developers                       4, fmlaCode, True, byElem=True)
145910037SARM gem5 Developers    threeEqualRegInstX("fmla", "FmlaElemScX", "SimdFloatMultAccOp", floatTypes,
146010037SARM gem5 Developers                       4, fmlaCode, True, byElem=True, scalar=True)
146110037SARM gem5 Developers    # FMLA (vector)
146210037SARM gem5 Developers    threeEqualRegInstX("fmla", "FmlaDX", "SimdFloatMultAccOp", smallFloatTypes,
146310037SARM gem5 Developers                       2, fmlaCode, True)
146410037SARM gem5 Developers    threeEqualRegInstX("fmla", "FmlaQX", "SimdFloatMultAccOp", floatTypes, 4,
146510037SARM gem5 Developers                       fmlaCode, True)
146610037SARM gem5 Developers    # FMLS (by element)
146710037SARM gem5 Developers    fmlsCode = fpOp % ("fplibMulAdd<Element>(destElem,"
146810037SARM gem5 Developers                       " fplibNeg<Element>(srcElem1), srcElem2, fpscr)")
146910037SARM gem5 Developers    threeEqualRegInstX("fmls", "FmlsElemDX", "SimdFloatMultAccOp",
147010037SARM gem5 Developers                       smallFloatTypes, 2, fmlsCode, True, byElem=True)
147110037SARM gem5 Developers    threeEqualRegInstX("fmls", "FmlsElemQX", "SimdFloatMultAccOp", floatTypes,
147210037SARM gem5 Developers                       4, fmlsCode, True, byElem=True)
147310037SARM gem5 Developers    threeEqualRegInstX("fmls", "FmlsElemScX", "SimdFloatMultAccOp", floatTypes,
147410037SARM gem5 Developers                       4, fmlsCode, True, byElem=True, scalar=True)
147510037SARM gem5 Developers    # FMLS (vector)
147610037SARM gem5 Developers    threeEqualRegInstX("fmls", "FmlsDX", "SimdFloatMultAccOp", smallFloatTypes,
147710037SARM gem5 Developers                       2, fmlsCode, True)
147810037SARM gem5 Developers    threeEqualRegInstX("fmls", "FmlsQX", "SimdFloatMultAccOp", floatTypes, 4,
147910037SARM gem5 Developers                       fmlsCode, True)
148010037SARM gem5 Developers    # FMOV
148110037SARM gem5 Developers    fmovCode = 'destElem = imm;'
148210037SARM gem5 Developers    oneRegImmInstX("fmov", "FmovDX", "SimdMiscOp", smallFloatTypes, 2,
148310037SARM gem5 Developers                   fmovCode)
148410037SARM gem5 Developers    oneRegImmInstX("fmov", "FmovQX", "SimdMiscOp", floatTypes, 4, fmovCode)
148510037SARM gem5 Developers    # FMUL (by element)
148610037SARM gem5 Developers    fmulCode = fpBinOp % "Mul"
148710037SARM gem5 Developers    threeEqualRegInstX("fmul", "FmulElemDX", "SimdFloatMultOp",
148810037SARM gem5 Developers                       smallFloatTypes, 2, fmulCode, byElem=True)
148910037SARM gem5 Developers    threeEqualRegInstX("fmul", "FmulElemQX", "SimdFloatMultOp", floatTypes, 4,
149010037SARM gem5 Developers                       fmulCode, byElem=True)
149110037SARM gem5 Developers    threeEqualRegInstX("fmul", "FmulElemScX", "SimdFloatMultOp", floatTypes, 4,
149210037SARM gem5 Developers                       fmulCode, byElem=True, scalar=True)
149310037SARM gem5 Developers    # FMUL (vector)
149410037SARM gem5 Developers    threeEqualRegInstX("fmul", "FmulDX", "SimdFloatMultOp", smallFloatTypes, 2,
149510037SARM gem5 Developers                       fmulCode)
149610037SARM gem5 Developers    threeEqualRegInstX("fmul", "FmulQX", "SimdFloatMultOp", floatTypes, 4,
149710037SARM gem5 Developers                       fmulCode)
149810037SARM gem5 Developers    # FMULX
149910037SARM gem5 Developers    fmulxCode = fpBinOp % "MulX"
150010037SARM gem5 Developers    threeEqualRegInstX("fmulx", "FmulxDX", "SimdFloatMultOp", smallFloatTypes,
150110037SARM gem5 Developers                       2, fmulxCode)
150210037SARM gem5 Developers    threeEqualRegInstX("fmulx", "FmulxQX", "SimdFloatMultOp", floatTypes, 4,
150310037SARM gem5 Developers                       fmulxCode)
150410037SARM gem5 Developers    threeEqualRegInstX("fmulx", "FmulxScX", "SimdFloatMultOp", floatTypes, 4,
150510037SARM gem5 Developers                       fmulxCode, scalar=True)
150610037SARM gem5 Developers    # FMULX (by element)
150710037SARM gem5 Developers    threeEqualRegInstX("fmulx", "FmulxElemDX", "SimdFloatMultOp",
150810037SARM gem5 Developers                       smallFloatTypes, 2, fmulxCode, byElem=True)
150910037SARM gem5 Developers    threeEqualRegInstX("fmulx", "FmulxElemQX", "SimdFloatMultOp", floatTypes,
151010037SARM gem5 Developers                       4, fmulxCode, byElem=True)
151110037SARM gem5 Developers    threeEqualRegInstX("fmulx", "FmulxElemScX", "SimdFloatMultOp", floatTypes,
151210037SARM gem5 Developers                       4, fmulxCode, byElem=True, scalar=True)
151310037SARM gem5 Developers    # FNEG
151410037SARM gem5 Developers    fnegCode = fpOp % "fplibNeg<Element>(srcElem1)"
151510037SARM gem5 Developers    twoEqualRegInstX("Neg", "FnegDX", "SimdFloatAluOp", smallFloatTypes, 2,
151610037SARM gem5 Developers                     fnegCode)
151710037SARM gem5 Developers    twoEqualRegInstX("Neg", "FnegQX", "SimdFloatAluOp", floatTypes, 4,
151810037SARM gem5 Developers                     fnegCode)
151910037SARM gem5 Developers    # FRECPE
152010037SARM gem5 Developers    frecpeCode = fpOp % "fplibRecipEstimate<Element>(srcElem1, fpscr)"
152110037SARM gem5 Developers    twoEqualRegInstX("frecpe", "FrecpeDX", "SimdFloatMultAccOp",
152210037SARM gem5 Developers                     smallFloatTypes, 2, frecpeCode)
152310037SARM gem5 Developers    twoEqualRegInstX("frecpe", "FrecpeQX", "SimdFloatMultAccOp", floatTypes, 4,
152410037SARM gem5 Developers                     frecpeCode)
152510037SARM gem5 Developers    twoEqualRegInstX("frecpe", "FrecpeScX", "SimdFloatMultAccOp", floatTypes,
152610037SARM gem5 Developers                     4, frecpeCode, scalar=True)
152710037SARM gem5 Developers    # FRECPS
152810037SARM gem5 Developers    frecpsCode = fpBinOp % "RecipStepFused"
152910037SARM gem5 Developers    threeEqualRegInstX("frecps", "FrecpsDX", "SimdFloatMultAccOp",
153010037SARM gem5 Developers                       smallFloatTypes, 2, frecpsCode)
153110037SARM gem5 Developers    threeEqualRegInstX("frecps", "FrecpsQX", "SimdFloatMultAccOp", floatTypes,
153210037SARM gem5 Developers                       4, frecpsCode)
153310037SARM gem5 Developers    threeEqualRegInstX("frecps", "FrecpsScX", "SimdFloatMultAccOp", floatTypes,
153410037SARM gem5 Developers                       4, frecpsCode, scalar=True)
153510037SARM gem5 Developers    # FRECPX
153610037SARM gem5 Developers    frecpxCode = fpOp % "fplibRecpX<Element>(srcElem1, fpscr)"
153710037SARM gem5 Developers    twoEqualRegInstX("frecpx", "FrecpxX", "SimdFloatMultAccOp", floatTypes, 4,
153810037SARM gem5 Developers                     frecpxCode, scalar=True)
153910037SARM gem5 Developers    # FRINTA
154010037SARM gem5 Developers    frintCode = fpOp % "fplibRoundInt<Element>(srcElem1, %s, %s, fpscr)"
154110037SARM gem5 Developers    frintaCode = frintCode % ("FPRounding_TIEAWAY", "false")
154210037SARM gem5 Developers    twoEqualRegInstX("frinta", "FrintaDX", "SimdCvtOp", smallFloatTypes, 2,
154310037SARM gem5 Developers                     frintaCode)
154410037SARM gem5 Developers    twoEqualRegInstX("frinta", "FrintaQX", "SimdCvtOp", floatTypes, 4,
154510037SARM gem5 Developers                     frintaCode)
154610037SARM gem5 Developers    # FRINTI
154710037SARM gem5 Developers    frintiCode = frintCode % ("FPCRRounding(fpscr)", "false")
154810037SARM gem5 Developers    twoEqualRegInstX("frinti", "FrintiDX", "SimdCvtOp", smallFloatTypes, 2,
154910037SARM gem5 Developers                     frintiCode)
155010037SARM gem5 Developers    twoEqualRegInstX("frinti", "FrintiQX", "SimdCvtOp", floatTypes, 4,
155110037SARM gem5 Developers                     frintiCode)
155210037SARM gem5 Developers    # FRINTM
155310037SARM gem5 Developers    frintmCode = frintCode % ("FPRounding_NEGINF", "false")
155410037SARM gem5 Developers    twoEqualRegInstX("frintm", "FrintmDX", "SimdCvtOp", smallFloatTypes, 2,
155510037SARM gem5 Developers                     frintmCode)
155610037SARM gem5 Developers    twoEqualRegInstX("frintm", "FrintmQX", "SimdCvtOp", floatTypes, 4,
155710037SARM gem5 Developers                     frintmCode)
155810037SARM gem5 Developers    # FRINTN
155910037SARM gem5 Developers    frintnCode = frintCode % ("FPRounding_TIEEVEN", "false")
156010037SARM gem5 Developers    twoEqualRegInstX("frintn", "FrintnDX", "SimdCvtOp", smallFloatTypes, 2,
156110037SARM gem5 Developers                     frintnCode)
156210037SARM gem5 Developers    twoEqualRegInstX("frintn", "FrintnQX", "SimdCvtOp", floatTypes, 4,
156310037SARM gem5 Developers                     frintnCode)
156410037SARM gem5 Developers    # FRINTP
156510037SARM gem5 Developers    frintpCode = frintCode % ("FPRounding_POSINF", "false")
156610037SARM gem5 Developers    twoEqualRegInstX("frintp", "FrintpDX", "SimdCvtOp", smallFloatTypes, 2,
156710037SARM gem5 Developers                     frintpCode)
156810037SARM gem5 Developers    twoEqualRegInstX("frintp", "FrintpQX", "SimdCvtOp", floatTypes, 4,
156910037SARM gem5 Developers                     frintpCode)
157010037SARM gem5 Developers    # FRINTX
157110037SARM gem5 Developers    frintxCode = frintCode % ("FPCRRounding(fpscr)", "true")
157210037SARM gem5 Developers    twoEqualRegInstX("frintx", "FrintxDX", "SimdCvtOp", smallFloatTypes, 2,
157310037SARM gem5 Developers                     frintxCode)
157410037SARM gem5 Developers    twoEqualRegInstX("frintx", "FrintxQX", "SimdCvtOp", floatTypes, 4,
157510037SARM gem5 Developers                     frintxCode)
157610037SARM gem5 Developers    # FRINTZ
157710037SARM gem5 Developers    frintzCode = frintCode % ("FPRounding_ZERO", "false")
157810037SARM gem5 Developers    twoEqualRegInstX("frintz", "FrintzDX", "SimdCvtOp", smallFloatTypes, 2,
157910037SARM gem5 Developers                     frintzCode)
158010037SARM gem5 Developers    twoEqualRegInstX("frintz", "FrintzQX", "SimdCvtOp", floatTypes, 4,
158110037SARM gem5 Developers                     frintzCode)
158210037SARM gem5 Developers    # FRSQRTE
158310037SARM gem5 Developers    frsqrteCode = fpOp % "fplibRSqrtEstimate<Element>(srcElem1, fpscr)"
158410037SARM gem5 Developers    twoEqualRegInstX("frsqrte", "FrsqrteDX", "SimdFloatSqrtOp",
158510037SARM gem5 Developers                     smallFloatTypes, 2, frsqrteCode)
158610037SARM gem5 Developers    twoEqualRegInstX("frsqrte", "FrsqrteQX", "SimdFloatSqrtOp", floatTypes, 4,
158710037SARM gem5 Developers                     frsqrteCode)
158810037SARM gem5 Developers    twoEqualRegInstX("frsqrte", "FrsqrteScX", "SimdFloatSqrtOp", floatTypes, 4,
158910037SARM gem5 Developers                     frsqrteCode, scalar=True)
159010037SARM gem5 Developers    # FRSQRTS
159110037SARM gem5 Developers    frsqrtsCode = fpBinOp % "RSqrtStepFused"
159210037SARM gem5 Developers    threeEqualRegInstX("frsqrts", "FrsqrtsDX", "SimdFloatMiscOp",
159310037SARM gem5 Developers                       smallFloatTypes, 2, frsqrtsCode)
159410037SARM gem5 Developers    threeEqualRegInstX("frsqrts", "FrsqrtsQX", "SimdFloatMiscOp", floatTypes,
159510037SARM gem5 Developers                       4, frsqrtsCode)
159610037SARM gem5 Developers    threeEqualRegInstX("frsqrts", "FrsqrtsScX", "SimdFloatMiscOp", floatTypes,
159710037SARM gem5 Developers                       4, frsqrtsCode, scalar=True)
159810037SARM gem5 Developers    # FSQRT
159910037SARM gem5 Developers    fsqrtCode = fpOp % "fplibSqrt<Element>(srcElem1, fpscr)"
160010037SARM gem5 Developers    twoEqualRegInstX("fsqrt", "FsqrtDX", "SimdFloatSqrtOp", smallFloatTypes, 2,
160110037SARM gem5 Developers                     fsqrtCode)
160210037SARM gem5 Developers    twoEqualRegInstX("fsqrt", "FsqrtQX", "SimdFloatSqrtOp", floatTypes, 4,
160310037SARM gem5 Developers                     fsqrtCode)
160410037SARM gem5 Developers    # FSUB
160510037SARM gem5 Developers    fsubCode = fpBinOp % "Sub"
160610037SARM gem5 Developers    threeEqualRegInstX("fsub", "FsubDX", "SimdFloatAddOp", smallFloatTypes, 2,
160710037SARM gem5 Developers                       fsubCode)
160810037SARM gem5 Developers    threeEqualRegInstX("fsub", "FsubQX", "SimdFloatAddOp", floatTypes, 4,
160910037SARM gem5 Developers                       fsubCode)
161010037SARM gem5 Developers    # INS (element)
161110037SARM gem5 Developers    insFromVecElemInstX("ins", "InsElemX", "SimdMiscOp", unsignedTypes, 4)
161210037SARM gem5 Developers    # INS (general register)
161310037SARM gem5 Developers    insFromGprInstX("ins", "InsGprWX", "SimdMiscOp", smallUnsignedTypes, 4,
161410037SARM gem5 Developers                    'W')
161510037SARM gem5 Developers    insFromGprInstX("ins", "InsGprXX", "SimdMiscOp", unsignedTypes, 4, 'X')
161610037SARM gem5 Developers    # MLA (by element)
161710037SARM gem5 Developers    mlaCode = "destElem += srcElem1 * srcElem2;"
161810037SARM gem5 Developers    threeEqualRegInstX("mla", "MlaElemDX", "SimdMultAccOp",
161910037SARM gem5 Developers                       ("uint16_t", "uint32_t"), 2, mlaCode, True, byElem=True)
162010037SARM gem5 Developers    threeEqualRegInstX("mla", "MlaElemQX", "SimdMultAccOp",
162110037SARM gem5 Developers                       ("uint16_t", "uint32_t"), 4, mlaCode, True, byElem=True)
162210037SARM gem5 Developers    # MLA (vector)
162310037SARM gem5 Developers    threeEqualRegInstX("mla", "MlaDX", "SimdMultAccOp", smallUnsignedTypes, 2,
162410037SARM gem5 Developers                       mlaCode, True)
162510037SARM gem5 Developers    threeEqualRegInstX("mla", "MlaQX", "SimdMultAccOp", smallUnsignedTypes, 4,
162610037SARM gem5 Developers                       mlaCode, True)
162710037SARM gem5 Developers    # MLS (by element)
162810037SARM gem5 Developers    mlsCode = "destElem -= srcElem1 * srcElem2;"
162910037SARM gem5 Developers    threeEqualRegInstX("mls", "MlsElemDX", "SimdMultAccOp",
163010037SARM gem5 Developers                       ("uint16_t", "uint32_t"), 2, mlsCode, True, byElem=True)
163110037SARM gem5 Developers    threeEqualRegInstX("mls", "MlsElemQX", "SimdMultAccOp",
163210037SARM gem5 Developers                       ("uint16_t", "uint32_t"), 4, mlsCode, True, byElem=True)
163310037SARM gem5 Developers    # MLS (vector)
163410037SARM gem5 Developers    threeEqualRegInstX("mls", "MlsDX", "SimdMultAccOp", smallUnsignedTypes, 2,
163510037SARM gem5 Developers                       mlsCode, True)
163610037SARM gem5 Developers    threeEqualRegInstX("mls", "MlsQX", "SimdMultAccOp", smallUnsignedTypes, 4,
163710037SARM gem5 Developers                       mlsCode, True)
163810037SARM gem5 Developers    # MOV (element) -> alias to INS (element)
163910037SARM gem5 Developers    # MOV (from general) -> alias to INS (general register)
164010037SARM gem5 Developers    # MOV (scalar) -> alias to DUP (element)
164110037SARM gem5 Developers    # MOV (to general) -> alias to UMOV
164210037SARM gem5 Developers    # MOV (vector) -> alias to ORR (register)
164310037SARM gem5 Developers    # MOVI
164410037SARM gem5 Developers    movImmCode = "destElem = imm;"
164510037SARM gem5 Developers    oneRegImmInstX("movi", "MoviDX", "SimdMiscOp", ("uint64_t",), 2,
164610037SARM gem5 Developers                   movImmCode)
164710037SARM gem5 Developers    oneRegImmInstX("movi", "MoviQX", "SimdMiscOp", ("uint64_t",), 4,
164810037SARM gem5 Developers                   movImmCode)
164910037SARM gem5 Developers    # MUL (by element)
165010037SARM gem5 Developers    mulCode = "destElem = srcElem1 * srcElem2;"
165110037SARM gem5 Developers    threeEqualRegInstX("mul", "MulElemDX", "SimdMultOp",
165210037SARM gem5 Developers                       ("uint16_t", "uint32_t"), 2, mulCode, byElem=True)
165310037SARM gem5 Developers    threeEqualRegInstX("mul", "MulElemQX", "SimdMultOp",
165410037SARM gem5 Developers                       ("uint16_t", "uint32_t"), 4, mulCode, byElem=True)
165510037SARM gem5 Developers    # MUL (vector)
165610037SARM gem5 Developers    threeEqualRegInstX("mul", "MulDX", "SimdMultOp", smallUnsignedTypes, 2,
165710037SARM gem5 Developers                       mulCode)
165810037SARM gem5 Developers    threeEqualRegInstX("mul", "MulQX", "SimdMultOp", smallUnsignedTypes, 4,
165910037SARM gem5 Developers                       mulCode)
166010037SARM gem5 Developers    # MVN
166110037SARM gem5 Developers    mvnCode = "destElem = ~srcElem1;"
166210037SARM gem5 Developers    twoEqualRegInstX("mvn", "MvnDX", "SimdAluOp", ("uint64_t",), 2, mvnCode)
166310037SARM gem5 Developers    twoEqualRegInstX("mvn", "MvnQX", "SimdAluOp", ("uint64_t",), 4, mvnCode)
166410037SARM gem5 Developers    # MVNI
166510037SARM gem5 Developers    mvniCode = "destElem = ~imm;"
166610037SARM gem5 Developers    oneRegImmInstX("mvni", "MvniDX", "SimdAluOp", ("uint64_t",), 2, mvniCode)
166710037SARM gem5 Developers    oneRegImmInstX("mvni", "MvniQX", "SimdAluOp", ("uint64_t",), 4, mvniCode)
166810037SARM gem5 Developers    # NEG
166910037SARM gem5 Developers    negCode = "destElem = -srcElem1;"
167010037SARM gem5 Developers    twoEqualRegInstX("neg", "NegDX", "SimdAluOp", signedTypes, 2, negCode)
167110037SARM gem5 Developers    twoEqualRegInstX("neg", "NegQX", "SimdAluOp", signedTypes, 4, negCode)
167210037SARM gem5 Developers    # NOT -> alias to MVN
167310037SARM gem5 Developers    # ORN
167410037SARM gem5 Developers    ornCode = "destElem = srcElem1 | ~srcElem2;"
167510037SARM gem5 Developers    threeEqualRegInstX("orn", "OrnDX", "SimdAluOp", ("uint64_t",), 2, ornCode)
167610037SARM gem5 Developers    threeEqualRegInstX("orn", "OrnQX", "SimdAluOp", ("uint64_t",), 4, ornCode)
167710037SARM gem5 Developers    # ORR (immediate)
167810037SARM gem5 Developers    orrImmCode = "destElem |= imm;"
167910037SARM gem5 Developers    oneRegImmInstX("orr", "OrrImmDX", "SimdAluOp", ("uint64_t",), 2,
168010037SARM gem5 Developers                   orrImmCode, True)
168110037SARM gem5 Developers    oneRegImmInstX("orr", "OrrImmQX", "SimdAluOp", ("uint64_t",), 4,
168210037SARM gem5 Developers                   orrImmCode, True)
168310037SARM gem5 Developers    # ORR (register)
168410037SARM gem5 Developers    orrCode = "destElem = srcElem1 | srcElem2;"
168510037SARM gem5 Developers    threeEqualRegInstX("orr", "OrrDX", "SimdAluOp", ("uint64_t",), 2, orrCode)
168610037SARM gem5 Developers    threeEqualRegInstX("orr", "OrrQX", "SimdAluOp", ("uint64_t",), 4, orrCode)
168710037SARM gem5 Developers    # PMUL
168810037SARM gem5 Developers    pmulCode = '''
168910037SARM gem5 Developers            destElem = 0;
169010037SARM gem5 Developers            for (unsigned j = 0; j < sizeof(Element) * 8; j++) {
169110037SARM gem5 Developers                if (bits(srcElem2, j))
169210037SARM gem5 Developers                    destElem ^= srcElem1 << j;
169310037SARM gem5 Developers            }
169410037SARM gem5 Developers    '''
169510037SARM gem5 Developers    threeEqualRegInstX("pmul", "PmulDX", "SimdMultOp", ("uint8_t",), 2,
169610037SARM gem5 Developers                       pmulCode)
169710037SARM gem5 Developers    threeEqualRegInstX("pmul", "PmulQX", "SimdMultOp", ("uint8_t",), 4,
169810037SARM gem5 Developers                       pmulCode)
169910037SARM gem5 Developers    # PMULL, PMULL2
170010037SARM gem5 Developers    # Note: 64-bit PMULL is not available (Crypto. Extension)
170110037SARM gem5 Developers    pmullCode = '''
170210037SARM gem5 Developers            destElem = 0;
170310037SARM gem5 Developers            for (unsigned j = 0; j < sizeof(Element) * 8; j++) {
170410037SARM gem5 Developers                if (bits(srcElem2, j))
170510037SARM gem5 Developers                    destElem ^= (BigElement)srcElem1 << j;
170610037SARM gem5 Developers            }
170710037SARM gem5 Developers    '''
170810037SARM gem5 Developers    threeRegLongInstX("pmull", "PmullX", "SimdMultOp", ("uint8_t",), pmullCode)
170910037SARM gem5 Developers    threeRegLongInstX("pmull", "Pmull2X", "SimdMultOp", ("uint8_t",),
171010037SARM gem5 Developers                      pmullCode, hi=True)
171110037SARM gem5 Developers    # RADDHN, RADDHN2
171210037SARM gem5 Developers    raddhnCode = '''
171310037SARM gem5 Developers            destElem = ((BigElement)srcElem1 + (BigElement)srcElem2 +
171410037SARM gem5 Developers                        ((BigElement)1 << (sizeof(Element) * 8 - 1))) >>
171510037SARM gem5 Developers                       (sizeof(Element) * 8);
171610037SARM gem5 Developers    '''
171710037SARM gem5 Developers    threeRegNarrowInstX("raddhn", "RaddhnX", "SimdAddOp", smallUnsignedTypes,
171810037SARM gem5 Developers                        raddhnCode)
171910037SARM gem5 Developers    threeRegNarrowInstX("raddhn2", "Raddhn2X", "SimdAddOp", smallUnsignedTypes,
172010037SARM gem5 Developers                        raddhnCode, hi=True)
172110037SARM gem5 Developers    # RBIT
172210037SARM gem5 Developers    rbitCode = '''
172310037SARM gem5 Developers            destElem = 0;
172410037SARM gem5 Developers            Element temp = srcElem1;
172510037SARM gem5 Developers            for (int i = 0; i < 8 * sizeof(Element); i++) {
172610037SARM gem5 Developers                destElem = destElem  | ((temp & 0x1) <<
172710037SARM gem5 Developers                                        (8 * sizeof(Element) - 1 - i));
172810037SARM gem5 Developers                temp >>= 1;
172910037SARM gem5 Developers            }
173010037SARM gem5 Developers    '''
173110037SARM gem5 Developers    twoEqualRegInstX("rbit", "RbitDX", "SimdAluOp", ("uint8_t",), 2, rbitCode)
173210037SARM gem5 Developers    twoEqualRegInstX("rbit", "RbitQX", "SimdAluOp", ("uint8_t",), 4, rbitCode)
173310037SARM gem5 Developers    # REV16
173410037SARM gem5 Developers    rev16Code = '''
173510037SARM gem5 Developers            destElem = srcElem1;
173610037SARM gem5 Developers            unsigned groupSize = ((1 << 1) / sizeof(Element));
173710037SARM gem5 Developers            unsigned reverseMask = (groupSize - 1);
173810037SARM gem5 Developers            j = i ^ reverseMask;
173910037SARM gem5 Developers    '''
174010037SARM gem5 Developers    twoEqualRegInstX("rev16", "Rev16DX", "SimdAluOp", ("uint8_t",), 2,
174110037SARM gem5 Developers                     rev16Code)
174210037SARM gem5 Developers    twoEqualRegInstX("rev16", "Rev16QX", "SimdAluOp", ("uint8_t",), 4,
174310037SARM gem5 Developers                     rev16Code)
174410037SARM gem5 Developers    # REV32
174510037SARM gem5 Developers    rev32Code = '''
174610037SARM gem5 Developers            destElem = srcElem1;
174710037SARM gem5 Developers            unsigned groupSize = ((1 << 2) / sizeof(Element));
174810037SARM gem5 Developers            unsigned reverseMask = (groupSize - 1);
174910037SARM gem5 Developers            j = i ^ reverseMask;
175010037SARM gem5 Developers    '''
175110037SARM gem5 Developers    twoEqualRegInstX("rev32", "Rev32DX", "SimdAluOp", ("uint8_t", "uint16_t"),
175210037SARM gem5 Developers                     2, rev32Code)
175310037SARM gem5 Developers    twoEqualRegInstX("rev32", "Rev32QX", "SimdAluOp", ("uint8_t", "uint16_t"),
175410037SARM gem5 Developers                     4, rev32Code)
175510037SARM gem5 Developers    # REV64
175610037SARM gem5 Developers    rev64Code = '''
175710037SARM gem5 Developers            destElem = srcElem1;
175810037SARM gem5 Developers            unsigned groupSize = ((1 << 3) / sizeof(Element));
175910037SARM gem5 Developers            unsigned reverseMask = (groupSize - 1);
176010037SARM gem5 Developers            j = i ^ reverseMask;
176110037SARM gem5 Developers    '''
176210037SARM gem5 Developers    twoEqualRegInstX("rev64", "Rev64DX", "SimdAluOp", smallUnsignedTypes, 2,
176310037SARM gem5 Developers                     rev64Code)
176410037SARM gem5 Developers    twoEqualRegInstX("rev64", "Rev64QX", "SimdAluOp", smallUnsignedTypes, 4,
176510037SARM gem5 Developers                     rev64Code)
176610037SARM gem5 Developers    # RSHRN, RSHRN2
176710037SARM gem5 Developers    rshrnCode = '''
176810037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
176910037SARM gem5 Developers                destElem = 0;
177010037SARM gem5 Developers            } else if (imm) {
177110037SARM gem5 Developers                Element rBit = bits(srcElem1, imm - 1);
177210037SARM gem5 Developers                destElem = ((srcElem1 >> (imm - 1)) >> 1) + rBit;
177310037SARM gem5 Developers            } else {
177410037SARM gem5 Developers                destElem = srcElem1;
177510037SARM gem5 Developers            }
177610037SARM gem5 Developers    '''
177710037SARM gem5 Developers    twoRegNarrowInstX("rshrn", "RshrnX", "SimdShiftOp", smallUnsignedTypes,
177810037SARM gem5 Developers                      rshrnCode, hasImm=True)
177910037SARM gem5 Developers    twoRegNarrowInstX("rshrn2", "Rshrn2X", "SimdShiftOp", smallUnsignedTypes,
178010037SARM gem5 Developers                      rshrnCode, hasImm=True, hi=True)
178110037SARM gem5 Developers    # RSUBHN, RSUBHN2
178210037SARM gem5 Developers    rsubhnCode = '''
178310037SARM gem5 Developers            destElem = ((BigElement)srcElem1 - (BigElement)srcElem2 +
178410037SARM gem5 Developers                        ((BigElement)1 << (sizeof(Element) * 8 - 1))) >>
178510037SARM gem5 Developers                       (sizeof(Element) * 8);
178610037SARM gem5 Developers    '''
178710037SARM gem5 Developers    threeRegNarrowInstX("rsubhn", "RsubhnX", "SimdAddOp", smallTypes,
178810037SARM gem5 Developers                        rsubhnCode)
178910037SARM gem5 Developers    threeRegNarrowInstX("rsubhn2", "Rsubhn2X", "SimdAddOp", smallTypes,
179010037SARM gem5 Developers                        rsubhnCode, hi=True)
179110037SARM gem5 Developers    # SABA
179210037SARM gem5 Developers    abaCode = '''
179310037SARM gem5 Developers            destElem += (srcElem1 > srcElem2) ? (srcElem1 - srcElem2) :
179410037SARM gem5 Developers                                                (srcElem2 - srcElem1);
179510037SARM gem5 Developers    '''
179610037SARM gem5 Developers    threeEqualRegInstX("saba", "SabaDX", "SimdAddAccOp", smallSignedTypes, 2,
179710037SARM gem5 Developers                       abaCode, True)
179810037SARM gem5 Developers    threeEqualRegInstX("saba", "SabaQX", "SimdAddAccOp", smallSignedTypes, 4,
179910037SARM gem5 Developers                       abaCode, True)
180010037SARM gem5 Developers    # SABAL, SABAL2
180110037SARM gem5 Developers    abalCode = '''
180210037SARM gem5 Developers            destElem += (srcElem1 > srcElem2) ?
180310037SARM gem5 Developers                ((BigElement)srcElem1 - (BigElement)srcElem2) :
180410037SARM gem5 Developers                ((BigElement)srcElem2 - (BigElement)srcElem1);
180510037SARM gem5 Developers    '''
180610037SARM gem5 Developers    threeRegLongInstX("sabal", "SabalX", "SimdAddAccOp", smallSignedTypes,
180710037SARM gem5 Developers                      abalCode, True)
180810037SARM gem5 Developers    threeRegLongInstX("sabal2", "Sabal2X", "SimdAddAccOp", smallSignedTypes,
180910037SARM gem5 Developers                      abalCode, True, hi=True)
181010037SARM gem5 Developers    # SABD
181110037SARM gem5 Developers    abdCode = '''
181210037SARM gem5 Developers            destElem = (srcElem1 > srcElem2) ? (srcElem1 - srcElem2) :
181310037SARM gem5 Developers                                               (srcElem2 - srcElem1);
181410037SARM gem5 Developers    '''
181510037SARM gem5 Developers    threeEqualRegInstX("sabd", "SabdDX", "SimdAddOp", smallSignedTypes, 2,
181610037SARM gem5 Developers                       abdCode)
181710037SARM gem5 Developers    threeEqualRegInstX("sabd", "SabdQX", "SimdAddOp", smallSignedTypes, 4,
181810037SARM gem5 Developers                       abdCode)
181910037SARM gem5 Developers    # SABDL, SABDL2
182010037SARM gem5 Developers    abdlCode = '''
182110037SARM gem5 Developers            destElem = (srcElem1 > srcElem2) ?
182210037SARM gem5 Developers                ((BigElement)srcElem1 - (BigElement)srcElem2) :
182310037SARM gem5 Developers                ((BigElement)srcElem2 - (BigElement)srcElem1);
182410037SARM gem5 Developers    '''
182510037SARM gem5 Developers    threeRegLongInstX("sabdl", "SabdlX", "SimdAddAccOp", smallSignedTypes,
182610037SARM gem5 Developers                      abdlCode, True)
182710037SARM gem5 Developers    threeRegLongInstX("sabdl2", "Sabdl2X", "SimdAddAccOp", smallSignedTypes,
182810037SARM gem5 Developers                      abdlCode, True, hi=True)
182910037SARM gem5 Developers    # SADALP
183010037SARM gem5 Developers    adalpCode = "destElem += (BigElement)srcElem1 + (BigElement)srcElem2;"
183110037SARM gem5 Developers    twoRegCondenseInstX("sadalp", "SadalpDX", "SimdAddOp", smallSignedTypes, 2,
183210037SARM gem5 Developers                        adalpCode, True)
183310037SARM gem5 Developers    twoRegCondenseInstX("sadalp", "SadalpQX", "SimdAddOp", smallSignedTypes, 4,
183410037SARM gem5 Developers                        adalpCode, True)
183510037SARM gem5 Developers    # SADDL, SADDL2
183610037SARM gem5 Developers    addlwCode = "destElem = (BigElement)srcElem1 + (BigElement)srcElem2;"
183710037SARM gem5 Developers    threeRegLongInstX("saddl", "SaddlX", "SimdAddAccOp", smallSignedTypes,
183810037SARM gem5 Developers                      addlwCode)
183910037SARM gem5 Developers    threeRegLongInstX("saddl2", "Saddl2X", "SimdAddAccOp", smallSignedTypes,
184010037SARM gem5 Developers                      addlwCode, hi=True)
184110037SARM gem5 Developers    # SADDLP
184210037SARM gem5 Developers    twoRegCondenseInstX("saddlp", "SaddlpDX", "SimdAddOp", smallSignedTypes, 2,
184310037SARM gem5 Developers                        addlwCode)
184410037SARM gem5 Developers    twoRegCondenseInstX("saddlp", "SaddlpQX", "SimdAddOp", smallSignedTypes, 4,
184510037SARM gem5 Developers                        addlwCode)
184610037SARM gem5 Developers    # SADDLV
184710037SARM gem5 Developers    # Note: SimdAddOp can be a bit optimistic here
184810037SARM gem5 Developers    addAcrossLongCode = "destElem += (BigElement)srcElem1;"
184910037SARM gem5 Developers    twoRegAcrossInstX("saddlv", "SaddlvDX", "SimdAddOp", ("int8_t", "int16_t"),
185010037SARM gem5 Developers                      2, addAcrossLongCode, long=True)
185110037SARM gem5 Developers    twoRegAcrossInstX("saddlv", "SaddlvQX", "SimdAddOp", ("int8_t", "int16_t"),
185210037SARM gem5 Developers                      4, addAcrossLongCode, long=True)
185310037SARM gem5 Developers    twoRegAcrossInstX("saddlv", "SaddlvBQX", "SimdAddOp", ("int32_t",), 4,
185410037SARM gem5 Developers                      addAcrossLongCode, doubleDest=True, long=True)
185510037SARM gem5 Developers    # SADDW, SADDW2
185610037SARM gem5 Developers    threeRegWideInstX("saddw", "SaddwX", "SimdAddAccOp", smallSignedTypes,
185710037SARM gem5 Developers                      addlwCode)
185810037SARM gem5 Developers    threeRegWideInstX("saddw2", "Saddw2X", "SimdAddAccOp", smallSignedTypes,
185910037SARM gem5 Developers                      addlwCode, hi=True)
186010037SARM gem5 Developers    # SCVTF (fixed-point)
186110037SARM gem5 Developers    scvtfFixedCode = fpOp % ("fplibFixedToFP<Element>((int%d_t) srcElem1, imm,"
186210037SARM gem5 Developers                             " false, FPCRRounding(fpscr), fpscr)")
186310037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfFixedDX", "SimdCvtOp", smallFloatTypes, 2,
186410037SARM gem5 Developers                     scvtfFixedCode % 32, hasImm=True)
186510037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfFixedSQX", "SimdCvtOp", smallFloatTypes, 4,
186610037SARM gem5 Developers                     scvtfFixedCode % 32, hasImm=True)
186710037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfFixedDQX", "SimdCvtOp", ("uint64_t",), 4,
186810037SARM gem5 Developers                     scvtfFixedCode % 64, hasImm=True)
186910037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfFixedScSX", "SimdCvtOp", smallFloatTypes,
187010037SARM gem5 Developers                     4, scvtfFixedCode % 32, hasImm=True, scalar=True)
187110037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfFixedScDX", "SimdCvtOp", ("uint64_t",), 4,
187210037SARM gem5 Developers                     scvtfFixedCode % 64, hasImm=True, scalar=True)
187310037SARM gem5 Developers    # SCVTF (integer)
187410037SARM gem5 Developers    scvtfIntCode = fpOp % ("fplibFixedToFP<Element>((int%d_t) srcElem1, 0,"
187510037SARM gem5 Developers                           " false, FPCRRounding(fpscr), fpscr)")
187610037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfIntDX", "SimdCvtOp", smallFloatTypes, 2,
187710037SARM gem5 Developers                     scvtfIntCode % 32)
187810037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfIntSQX", "SimdCvtOp", smallFloatTypes, 4,
187910037SARM gem5 Developers                     scvtfIntCode % 32)
188010037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfIntDQX", "SimdCvtOp", ("uint64_t",), 4,
188110037SARM gem5 Developers                     scvtfIntCode % 64)
188210037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfIntScSX", "SimdCvtOp", smallFloatTypes, 4,
188310037SARM gem5 Developers                     scvtfIntCode % 32, scalar=True)
188410037SARM gem5 Developers    twoEqualRegInstX("scvtf", "ScvtfIntScDX", "SimdCvtOp", ("uint64_t",), 4,
188510037SARM gem5 Developers                     scvtfIntCode % 64, scalar=True)
188610037SARM gem5 Developers    # SHADD
188710037SARM gem5 Developers    haddCode = '''
188810037SARM gem5 Developers            Element carryBit =
188910037SARM gem5 Developers                (((unsigned)srcElem1 & 0x1) +
189010037SARM gem5 Developers                 ((unsigned)srcElem2 & 0x1)) >> 1;
189110037SARM gem5 Developers            // Use division instead of a shift to ensure the sign extension works
189210037SARM gem5 Developers            // right. The compiler will figure out if it can be a shift. Mask the
189310037SARM gem5 Developers            // inputs so they get truncated correctly.
189410037SARM gem5 Developers            destElem = (((srcElem1 & ~(Element)1) / 2) +
189510037SARM gem5 Developers                        ((srcElem2 & ~(Element)1) / 2)) + carryBit;
189610037SARM gem5 Developers    '''
189710037SARM gem5 Developers    threeEqualRegInstX("shadd", "ShaddDX", "SimdAddOp", smallSignedTypes, 2,
189810037SARM gem5 Developers                       haddCode)
189910037SARM gem5 Developers    threeEqualRegInstX("shadd", "ShaddQX", "SimdAddOp", smallSignedTypes, 4,
190010037SARM gem5 Developers                       haddCode)
190110037SARM gem5 Developers    # SHL
190210037SARM gem5 Developers    shlCode = '''
190310037SARM gem5 Developers            if (imm >= sizeof(Element) * 8)
190410037SARM gem5 Developers                destElem = (srcElem1 << (sizeof(Element) * 8 - 1)) << 1;
190510037SARM gem5 Developers            else
190610037SARM gem5 Developers                destElem = srcElem1 << imm;
190710037SARM gem5 Developers    '''
190810037SARM gem5 Developers    twoEqualRegInstX("shl", "ShlDX", "SimdShiftOp", unsignedTypes, 2, shlCode,
190910037SARM gem5 Developers                     hasImm=True)
191010037SARM gem5 Developers    twoEqualRegInstX("shl", "ShlQX", "SimdShiftOp", unsignedTypes, 4, shlCode,
191110037SARM gem5 Developers                     hasImm=True)
191210037SARM gem5 Developers    # SHLL, SHLL2
191310037SARM gem5 Developers    shllCode = "destElem = ((BigElement)srcElem1) << (sizeof(Element) * 8);"
191410037SARM gem5 Developers    twoRegLongInstX("shll", "ShllX", "SimdShiftOp", smallTypes, shllCode)
191510037SARM gem5 Developers    twoRegLongInstX("shll", "Shll2X", "SimdShiftOp", smallTypes, shllCode,
191610037SARM gem5 Developers                    hi=True)
191710037SARM gem5 Developers    # SHRN, SHRN2
191810037SARM gem5 Developers    shrnCode = '''
191910037SARM gem5 Developers            if (imm >= sizeof(srcElem1) * 8) {
192010037SARM gem5 Developers                destElem = 0;
192110037SARM gem5 Developers            } else {
192210037SARM gem5 Developers                destElem = srcElem1 >> imm;
192310037SARM gem5 Developers            }
192410037SARM gem5 Developers    '''
192510037SARM gem5 Developers    twoRegNarrowInstX("shrn", "ShrnX", "SimdShiftOp", smallUnsignedTypes,
192610037SARM gem5 Developers                      shrnCode, hasImm=True)
192710037SARM gem5 Developers    twoRegNarrowInstX("shrn2", "Shrn2X", "SimdShiftOp", smallUnsignedTypes,
192810037SARM gem5 Developers                      shrnCode, hasImm=True, hi=True)
192910037SARM gem5 Developers    # SHSUB
193010037SARM gem5 Developers    hsubCode = '''
193110037SARM gem5 Developers            Element borrowBit =
193210037SARM gem5 Developers                (((srcElem1 & 0x1) - (srcElem2 & 0x1)) >> 1) & 0x1;
193310037SARM gem5 Developers            // Use division instead of a shift to ensure the sign extension works
193410037SARM gem5 Developers            // right. The compiler will figure out if it can be a shift. Mask the
193510037SARM gem5 Developers            // inputs so they get truncated correctly.
193610037SARM gem5 Developers            destElem = (((srcElem1 & ~(Element)1) / 2) -
193710037SARM gem5 Developers                        ((srcElem2 & ~(Element)1) / 2)) - borrowBit;
193810037SARM gem5 Developers    '''
193910037SARM gem5 Developers    threeEqualRegInstX("shsub", "ShsubDX", "SimdAddOp", smallSignedTypes, 2,
194010037SARM gem5 Developers                       hsubCode)
194110037SARM gem5 Developers    threeEqualRegInstX("shsub", "ShsubQX", "SimdAddOp", smallSignedTypes, 4,
194210037SARM gem5 Developers                       hsubCode)
194310037SARM gem5 Developers    # SLI
194410037SARM gem5 Developers    sliCode = '''
194510037SARM gem5 Developers            if (imm >= sizeof(Element) * 8)
194610037SARM gem5 Developers                destElem = destElem;
194710037SARM gem5 Developers            else
194810037SARM gem5 Developers                destElem = (srcElem1 << imm) | (destElem & mask(imm));
194910037SARM gem5 Developers    '''
195010037SARM gem5 Developers    twoEqualRegInstX("sli", "SliDX", "SimdShiftOp", unsignedTypes, 2, sliCode,
195110037SARM gem5 Developers                     True, hasImm=True)
195210037SARM gem5 Developers    twoEqualRegInstX("sli", "SliQX", "SimdShiftOp", unsignedTypes, 4, sliCode,
195310037SARM gem5 Developers                     True, hasImm=True)
195410037SARM gem5 Developers    # SMAX
195510037SARM gem5 Developers    maxCode = "destElem = (srcElem1 > srcElem2) ? srcElem1 : srcElem2;"
195610037SARM gem5 Developers    threeEqualRegInstX("smax", "SmaxDX", "SimdCmpOp", smallSignedTypes, 2,
195710037SARM gem5 Developers                       maxCode)
195810037SARM gem5 Developers    threeEqualRegInstX("smax", "SmaxQX", "SimdCmpOp", smallSignedTypes, 4,
195910037SARM gem5 Developers                       maxCode)
196010037SARM gem5 Developers    # SMAXP
196110037SARM gem5 Developers    threeEqualRegInstX("smaxp", "SmaxpDX", "SimdCmpOp", smallSignedTypes, 2,
196210037SARM gem5 Developers                       maxCode, pairwise=True)
196310037SARM gem5 Developers    threeEqualRegInstX("smaxp", "SmaxpQX", "SimdCmpOp", smallSignedTypes, 4,
196410037SARM gem5 Developers                       maxCode, pairwise=True)
196510037SARM gem5 Developers    # SMAXV
196610037SARM gem5 Developers    maxAcrossCode = '''
196710037SARM gem5 Developers            if (i == 0 || srcElem1 > destElem)
196810037SARM gem5 Developers                destElem = srcElem1;
196910037SARM gem5 Developers    '''
197010037SARM gem5 Developers    twoRegAcrossInstX("smaxv", "SmaxvDX", "SimdCmpOp", ("int8_t", "int16_t"),
197110037SARM gem5 Developers                      2, maxAcrossCode)
197210037SARM gem5 Developers    twoRegAcrossInstX("smaxv", "SmaxvQX", "SimdCmpOp", smallSignedTypes, 4,
197310037SARM gem5 Developers                      maxAcrossCode)
197410037SARM gem5 Developers    # SMIN
197510037SARM gem5 Developers    minCode = "destElem = (srcElem1 < srcElem2) ? srcElem1 : srcElem2;"
197610037SARM gem5 Developers    threeEqualRegInstX("smin", "SminDX", "SimdCmpOp", smallSignedTypes, 2,
197710037SARM gem5 Developers                       minCode)
197810037SARM gem5 Developers    threeEqualRegInstX("smin", "SminQX", "SimdCmpOp", smallSignedTypes, 4,
197910037SARM gem5 Developers                       minCode)
198010037SARM gem5 Developers    # SMINP
198110037SARM gem5 Developers    threeEqualRegInstX("sminp", "SminpDX", "SimdCmpOp", smallSignedTypes, 2,
198210037SARM gem5 Developers                       minCode, pairwise=True)
198310037SARM gem5 Developers    threeEqualRegInstX("sminp", "SminpQX", "SimdCmpOp", smallSignedTypes, 4,
198410037SARM gem5 Developers                       minCode, pairwise=True)
198510037SARM gem5 Developers    # SMINV
198610037SARM gem5 Developers    minAcrossCode = '''
198710037SARM gem5 Developers            if (i == 0 || srcElem1 < destElem)
198810037SARM gem5 Developers                destElem = srcElem1;
198910037SARM gem5 Developers    '''
199010037SARM gem5 Developers    twoRegAcrossInstX("sminv", "SminvDX", "SimdCmpOp", ("int8_t", "int16_t"),
199110037SARM gem5 Developers                      2, minAcrossCode)
199210037SARM gem5 Developers    twoRegAcrossInstX("sminv", "SminvQX", "SimdCmpOp", smallSignedTypes, 4,
199310037SARM gem5 Developers                      minAcrossCode)
199410197SCurtis.Dunham@arm.com
199510197SCurtis.Dunham@arm.com    split('exec')
199610197SCurtis.Dunham@arm.com
199710037SARM gem5 Developers    # SMLAL, SMLAL2 (by element)
199810037SARM gem5 Developers    mlalCode = "destElem += (BigElement)srcElem1 * (BigElement)srcElem2;"
199910037SARM gem5 Developers    threeRegLongInstX("smlal", "SmlalElemX", "SimdMultAccOp",
200010037SARM gem5 Developers                      ("int16_t", "int32_t"), mlalCode, True, byElem=True)
200110037SARM gem5 Developers    threeRegLongInstX("smlal", "SmlalElem2X", "SimdMultAccOp",
200210037SARM gem5 Developers                      ("int16_t", "int32_t"), mlalCode, True, byElem=True,
200310037SARM gem5 Developers                      hi=True)
200410037SARM gem5 Developers    # SMLAL, SMLAL2 (vector)
200510037SARM gem5 Developers    threeRegLongInstX("smlal", "SmlalX", "SimdMultAccOp", smallSignedTypes,
200610037SARM gem5 Developers                      mlalCode, True)
200710037SARM gem5 Developers    threeRegLongInstX("smlal", "Smlal2X", "SimdMultAccOp", smallSignedTypes,
200810037SARM gem5 Developers                      mlalCode, True, hi=True)
200910037SARM gem5 Developers    # SMLSL, SMLSL2 (by element)
201010037SARM gem5 Developers    mlslCode = "destElem -= (BigElement)srcElem1 * (BigElement)srcElem2;"
201110037SARM gem5 Developers    threeRegLongInstX("smlsl", "SmlslElemX", "SimdMultAccOp", smallSignedTypes,
201210037SARM gem5 Developers                      mlslCode, True, byElem=True)
201310037SARM gem5 Developers    threeRegLongInstX("smlsl", "SmlslElem2X", "SimdMultAccOp",
201410037SARM gem5 Developers                      smallSignedTypes, mlslCode, True, byElem=True, hi=True)
201510037SARM gem5 Developers    # SMLSL, SMLSL2 (vector)
201610037SARM gem5 Developers    threeRegLongInstX("smlsl", "SmlslX", "SimdMultAccOp", smallSignedTypes,
201710037SARM gem5 Developers                      mlslCode, True)
201810037SARM gem5 Developers    threeRegLongInstX("smlsl", "Smlsl2X", "SimdMultAccOp", smallSignedTypes,
201910037SARM gem5 Developers                      mlslCode, True, hi=True)
202010037SARM gem5 Developers    # SMOV
202110037SARM gem5 Developers    insToGprInstX("smov", "SmovWX", "SimdMiscOp", ("int8_t", "int16_t"), 4,
202210037SARM gem5 Developers                  'W', True)
202310037SARM gem5 Developers    insToGprInstX("smov", "SmovXX", "SimdMiscOp", smallSignedTypes, 4, 'X',
202410037SARM gem5 Developers                  True)
202510037SARM gem5 Developers    # SMULL, SMULL2 (by element)
202610037SARM gem5 Developers    mullCode = "destElem = (BigElement)srcElem1 * (BigElement)srcElem2;"
202710037SARM gem5 Developers    threeRegLongInstX("smull", "SmullElemX", "SimdMultOp", smallSignedTypes,
202810037SARM gem5 Developers                      mullCode, byElem=True)
202910037SARM gem5 Developers    threeRegLongInstX("smull", "SmullElem2X", "SimdMultOp", smallSignedTypes,
203010037SARM gem5 Developers                      mullCode, byElem=True, hi=True)
203110037SARM gem5 Developers    # SMULL, SMULL2 (vector)
203210037SARM gem5 Developers    threeRegLongInstX("smull", "SmullX", "SimdMultOp", smallSignedTypes,
203310037SARM gem5 Developers                      mullCode)
203410037SARM gem5 Developers    threeRegLongInstX("smull", "Smull2X", "SimdMultOp", smallSignedTypes,
203510037SARM gem5 Developers                      mullCode, hi=True)
203610037SARM gem5 Developers    # SQABS
203710037SARM gem5 Developers    sqabsCode = '''
203810037SARM gem5 Developers        FPSCR fpscr = (FPSCR) FpscrQc;
203912038Srekai.gonzalezalberquilla@arm.com        if (srcElem1 == (Element)(std::numeric_limits<Element>::min())) {
204010037SARM gem5 Developers            fpscr.qc = 1;
204110037SARM gem5 Developers            destElem = ~srcElem1;
204210037SARM gem5 Developers        } else if (srcElem1 < 0) {
204310037SARM gem5 Developers            destElem = -srcElem1;
204410037SARM gem5 Developers        } else {
204510037SARM gem5 Developers            destElem = srcElem1;
204610037SARM gem5 Developers        }
204710037SARM gem5 Developers        FpscrQc = fpscr;
204810037SARM gem5 Developers    '''
204910037SARM gem5 Developers    twoEqualRegInstX("sqabs", "SqabsDX", "SimdAluOp", smallSignedTypes, 2,
205010037SARM gem5 Developers                     sqabsCode)
205110037SARM gem5 Developers    twoEqualRegInstX("sqabs", "SqabsQX", "SimdAluOp", signedTypes, 4,
205210037SARM gem5 Developers                     sqabsCode)
205310037SARM gem5 Developers    twoEqualRegInstX("sqabs", "SqabsScX", "SimdAluOp", signedTypes, 4,
205410037SARM gem5 Developers                     sqabsCode, scalar=True)
205510037SARM gem5 Developers    # SQADD
205610037SARM gem5 Developers    sqaddCode = '''
205710037SARM gem5 Developers            destElem = srcElem1 + srcElem2;
205810037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
205910037SARM gem5 Developers            bool negDest = (destElem < 0);
206010037SARM gem5 Developers            bool negSrc1 = (srcElem1 < 0);
206110037SARM gem5 Developers            bool negSrc2 = (srcElem2 < 0);
206210037SARM gem5 Developers            if ((negDest != negSrc1) && (negSrc1 == negSrc2)) {
206312038Srekai.gonzalezalberquilla@arm.com                destElem = std::numeric_limits<Element>::min();
206410037SARM gem5 Developers                if (negDest)
206510037SARM gem5 Developers                    destElem -= 1;
206610037SARM gem5 Developers                fpscr.qc = 1;
206710037SARM gem5 Developers            }
206810037SARM gem5 Developers            FpscrQc = fpscr;
206910037SARM gem5 Developers    '''
207010037SARM gem5 Developers    threeEqualRegInstX("sqadd", "SqaddDX", "SimdAddOp", smallSignedTypes, 2,
207110037SARM gem5 Developers                       sqaddCode)
207210037SARM gem5 Developers    threeEqualRegInstX("sqadd", "SqaddQX", "SimdAddOp", signedTypes, 4,
207310037SARM gem5 Developers                       sqaddCode)
207410037SARM gem5 Developers    threeEqualRegInstX("sqadd", "SqaddScX", "SimdAddOp", signedTypes, 4,
207510037SARM gem5 Developers                       sqaddCode, scalar=True)
207610037SARM gem5 Developers    # SQDMLAL, SQDMLAL2 (by element)
207710037SARM gem5 Developers    qdmlalCode = '''
207810037SARM gem5 Developers        FPSCR fpscr = (FPSCR) FpscrQc;
207910037SARM gem5 Developers        BigElement midElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
208012038Srekai.gonzalezalberquilla@arm.com        Element maxNeg = std::numeric_limits<Element>::min();
208110037SARM gem5 Developers        Element halfNeg = maxNeg / 2;
208210037SARM gem5 Developers        if ((srcElem1 == maxNeg && srcElem2 == maxNeg) ||
208310037SARM gem5 Developers            (srcElem1 == halfNeg && srcElem2 == maxNeg) ||
208410037SARM gem5 Developers            (srcElem1 == maxNeg && srcElem2 == halfNeg)) {
208510037SARM gem5 Developers            midElem = ~((BigElement)maxNeg << (sizeof(Element) * 8));
208610037SARM gem5 Developers            fpscr.qc = 1;
208710037SARM gem5 Developers        }
208810037SARM gem5 Developers        bool negPreDest = ltz(destElem);
208910037SARM gem5 Developers        destElem += midElem;
209010037SARM gem5 Developers        bool negDest = ltz(destElem);
209110037SARM gem5 Developers        bool negMid = ltz(midElem);
209210037SARM gem5 Developers        if (negPreDest == negMid && negMid != negDest) {
209310037SARM gem5 Developers            destElem = mask(sizeof(BigElement) * 8 - 1);
209410037SARM gem5 Developers            if (negPreDest)
209510037SARM gem5 Developers                destElem = ~destElem;
209610037SARM gem5 Developers            fpscr.qc = 1;
209710037SARM gem5 Developers        }
209810037SARM gem5 Developers        FpscrQc = fpscr;
209910037SARM gem5 Developers    '''
210010037SARM gem5 Developers    threeRegLongInstX("sqdmlal", "SqdmlalElemX", "SimdMultAccOp",
210110037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlalCode, True, byElem=True)
210210037SARM gem5 Developers    threeRegLongInstX("sqdmlal", "SqdmlalElem2X", "SimdMultAccOp",
210310037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlalCode, True, byElem=True,
210410037SARM gem5 Developers                      hi=True)
210510037SARM gem5 Developers    threeRegLongInstX("sqdmlal", "SqdmlalElemScX", "SimdMultAccOp",
210610037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlalCode, True, byElem=True,
210710037SARM gem5 Developers                      scalar=True)
210810037SARM gem5 Developers    # SQDMLAL, SQDMLAL2 (vector)
210910037SARM gem5 Developers    threeRegLongInstX("sqdmlal", "SqdmlalX", "SimdMultAccOp",
211010037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlalCode, True)
211110037SARM gem5 Developers    threeRegLongInstX("sqdmlal", "Sqdmlal2X", "SimdMultAccOp",
211210037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlalCode, True, hi=True)
211310037SARM gem5 Developers    threeRegLongInstX("sqdmlal", "SqdmlalScX", "SimdMultAccOp",
211410037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlalCode, True, scalar=True)
211510037SARM gem5 Developers    # SQDMLSL, SQDMLSL2 (by element)
211610037SARM gem5 Developers    qdmlslCode = '''
211710037SARM gem5 Developers        FPSCR fpscr = (FPSCR) FpscrQc;
211810037SARM gem5 Developers        BigElement midElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
211912038Srekai.gonzalezalberquilla@arm.com        Element maxNeg = std::numeric_limits<Element>::min();
212010037SARM gem5 Developers        Element halfNeg = maxNeg / 2;
212110037SARM gem5 Developers        if ((srcElem1 == maxNeg && srcElem2 == maxNeg) ||
212210037SARM gem5 Developers            (srcElem1 == halfNeg && srcElem2 == maxNeg) ||
212310037SARM gem5 Developers            (srcElem1 == maxNeg && srcElem2 == halfNeg)) {
212410037SARM gem5 Developers            midElem = ~((BigElement)maxNeg << (sizeof(Element) * 8));
212510037SARM gem5 Developers            fpscr.qc = 1;
212610037SARM gem5 Developers        }
212710037SARM gem5 Developers        bool negPreDest = ltz(destElem);
212810037SARM gem5 Developers        destElem -= midElem;
212910037SARM gem5 Developers        bool negDest = ltz(destElem);
213010037SARM gem5 Developers        bool posMid = ltz((BigElement)-midElem);
213110037SARM gem5 Developers        if (negPreDest == posMid && posMid != negDest) {
213210037SARM gem5 Developers            destElem = mask(sizeof(BigElement) * 8 - 1);
213310037SARM gem5 Developers            if (negPreDest)
213410037SARM gem5 Developers                destElem = ~destElem;
213510037SARM gem5 Developers            fpscr.qc = 1;
213610037SARM gem5 Developers        }
213710037SARM gem5 Developers        FpscrQc = fpscr;
213810037SARM gem5 Developers    '''
213910037SARM gem5 Developers    threeRegLongInstX("sqdmlsl", "SqdmlslElemX", "SimdMultAccOp",
214010037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlslCode, True, byElem=True)
214110037SARM gem5 Developers    threeRegLongInstX("sqdmlsl", "SqdmlslElem2X", "SimdMultAccOp",
214210037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlslCode, True, byElem=True,
214310037SARM gem5 Developers                      hi=True)
214410037SARM gem5 Developers    threeRegLongInstX("sqdmlsl", "SqdmlslElemScX", "SimdMultAccOp",
214510037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlslCode, True, byElem=True,
214610037SARM gem5 Developers                      scalar=True)
214710037SARM gem5 Developers    # SQDMLSL, SQDMLSL2 (vector)
214810037SARM gem5 Developers    threeRegLongInstX("sqdmlsl", "SqdmlslX", "SimdMultAccOp",
214910037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlslCode, True)
215010037SARM gem5 Developers    threeRegLongInstX("sqdmlsl", "Sqdmlsl2X", "SimdMultAccOp",
215110037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlslCode, True, hi=True)
215210037SARM gem5 Developers    threeRegLongInstX("sqdmlsl", "SqdmlslScX", "SimdMultAccOp",
215310037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmlslCode, True, scalar=True)
215410037SARM gem5 Developers    # SQDMULH (by element)
215510037SARM gem5 Developers    sqdmulhCode = '''
215610037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
215710037SARM gem5 Developers            destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2) >>
215810037SARM gem5 Developers                       (sizeof(Element) * 8);
215910037SARM gem5 Developers            if (srcElem1 == srcElem2 &&
216010037SARM gem5 Developers                    srcElem1 == (Element)((Element)1 <<
216110037SARM gem5 Developers                        (sizeof(Element) * 8 - 1))) {
216210037SARM gem5 Developers                destElem = ~srcElem1;
216310037SARM gem5 Developers                fpscr.qc = 1;
216410037SARM gem5 Developers            }
216510037SARM gem5 Developers            FpscrQc = fpscr;
216610037SARM gem5 Developers    '''
216710037SARM gem5 Developers    threeEqualRegInstX("sqdmulh", "SqdmulhElemDX", "SimdMultOp",
216810037SARM gem5 Developers                       ("int16_t", "int32_t"), 2, sqdmulhCode, byElem=True)
216910037SARM gem5 Developers    threeEqualRegInstX("sqdmulh", "SqdmulhElemQX", "SimdMultOp",
217010037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqdmulhCode, byElem=True)
217110037SARM gem5 Developers    threeEqualRegInstX("sqdmulh", "SqdmulhElemScX", "SimdMultOp",
217210037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqdmulhCode, byElem=True,
217310037SARM gem5 Developers                       scalar=True)
217410037SARM gem5 Developers    # SQDMULH (vector)
217510037SARM gem5 Developers    threeEqualRegInstX("sqdmulh", "SqdmulhDX", "SimdMultOp",
217610037SARM gem5 Developers                       ("int16_t", "int32_t"), 2, sqdmulhCode)
217710037SARM gem5 Developers    threeEqualRegInstX("sqdmulh", "SqdmulhQX", "SimdMultOp",
217810037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqdmulhCode)
217910037SARM gem5 Developers    threeEqualRegInstX("sqdmulh", "SqdmulhScX", "SimdMultOp",
218010037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqdmulhCode, scalar=True)
218110037SARM gem5 Developers    # SQDMULL, SQDMULL2 (by element)
218210037SARM gem5 Developers    qdmullCode = '''
218310037SARM gem5 Developers        FPSCR fpscr = (FPSCR) FpscrQc;
218410037SARM gem5 Developers        destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
218510037SARM gem5 Developers        if (srcElem1 == srcElem2 &&
218610037SARM gem5 Developers                srcElem1 == (Element)((Element)1 <<
218710037SARM gem5 Developers                    (Element)(sizeof(Element) * 8 - 1))) {
218810037SARM gem5 Developers            destElem = ~((BigElement)srcElem1 << (sizeof(Element) * 8));
218910037SARM gem5 Developers            fpscr.qc = 1;
219010037SARM gem5 Developers        }
219110037SARM gem5 Developers        FpscrQc = fpscr;
219210037SARM gem5 Developers    '''
219310037SARM gem5 Developers    threeRegLongInstX("sqdmull", "SqdmullElemX", "SimdMultOp",
219410037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmullCode, True, byElem=True)
219510037SARM gem5 Developers    threeRegLongInstX("sqdmull", "SqdmullElem2X", "SimdMultOp",
219610037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmullCode, True, byElem=True,
219710037SARM gem5 Developers                      hi=True)
219810037SARM gem5 Developers    threeRegLongInstX("sqdmull", "SqdmullElemScX", "SimdMultOp",
219910037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmullCode, True, byElem=True,
220010037SARM gem5 Developers                      scalar=True)
220110037SARM gem5 Developers    # SQDMULL, SQDMULL2 (vector)
220210037SARM gem5 Developers    threeRegLongInstX("sqdmull", "SqdmullX", "SimdMultOp",
220310037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmullCode, True)
220410037SARM gem5 Developers    threeRegLongInstX("sqdmull", "Sqdmull2X", "SimdMultOp",
220510037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmullCode, True, hi=True)
220610037SARM gem5 Developers    threeRegLongInstX("sqdmull", "SqdmullScX", "SimdMultOp",
220710037SARM gem5 Developers                      ("int16_t", "int32_t"), qdmullCode, True, scalar=True)
220810037SARM gem5 Developers    # SQNEG
220910037SARM gem5 Developers    sqnegCode = '''
221010037SARM gem5 Developers        FPSCR fpscr = (FPSCR) FpscrQc;
221112038Srekai.gonzalezalberquilla@arm.com        if (srcElem1 == (Element)(std::numeric_limits<Element>::min())) {
221210037SARM gem5 Developers            fpscr.qc = 1;
221310037SARM gem5 Developers            destElem = ~srcElem1;
221410037SARM gem5 Developers        } else {
221510037SARM gem5 Developers            destElem = -srcElem1;
221610037SARM gem5 Developers        }
221710037SARM gem5 Developers        FpscrQc = fpscr;
221810037SARM gem5 Developers    '''
221910037SARM gem5 Developers    twoEqualRegInstX("sqneg", "SqnegDX", "SimdAluOp", smallSignedTypes, 2,
222010037SARM gem5 Developers                     sqnegCode)
222110037SARM gem5 Developers    twoEqualRegInstX("sqneg", "SqnegQX", "SimdAluOp", signedTypes, 4,
222210037SARM gem5 Developers                     sqnegCode)
222310037SARM gem5 Developers    twoEqualRegInstX("sqneg", "SqnegScX", "SimdAluOp", signedTypes, 4,
222410037SARM gem5 Developers                     sqnegCode, scalar=True)
222510037SARM gem5 Developers    # SQRDMULH (by element)
222610037SARM gem5 Developers    sqrdmulhCode = '''
222710037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
222810037SARM gem5 Developers            destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2 +
222910037SARM gem5 Developers                        ((int64_t)1 << (sizeof(Element) * 8 - 1))) >>
223010037SARM gem5 Developers                       (sizeof(Element) * 8);
223112038Srekai.gonzalezalberquilla@arm.com            Element maxNeg = std::numeric_limits<Element>::min();
223210037SARM gem5 Developers            Element halfNeg = maxNeg / 2;
223310037SARM gem5 Developers            if ((srcElem1 == maxNeg && srcElem2 == maxNeg) ||
223410037SARM gem5 Developers                (srcElem1 == halfNeg && srcElem2 == maxNeg) ||
223510037SARM gem5 Developers                (srcElem1 == maxNeg && srcElem2 == halfNeg)) {
223610037SARM gem5 Developers                if (destElem < 0) {
223710037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8 - 1);
223810037SARM gem5 Developers                } else {
223912038Srekai.gonzalezalberquilla@arm.com                    destElem = std::numeric_limits<Element>::min();
224010037SARM gem5 Developers                }
224110037SARM gem5 Developers                fpscr.qc = 1;
224210037SARM gem5 Developers            }
224310037SARM gem5 Developers            FpscrQc = fpscr;
224410037SARM gem5 Developers    '''
224510037SARM gem5 Developers    threeEqualRegInstX("sqrdmulh", "SqrdmulhElemDX", "SimdMultOp",
224610037SARM gem5 Developers                       ("int16_t", "int32_t"), 2, sqrdmulhCode, byElem=True)
224710037SARM gem5 Developers    threeEqualRegInstX("sqrdmulh", "SqrdmulhElemQX", "SimdMultOp",
224810037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqrdmulhCode, byElem=True)
224910037SARM gem5 Developers    threeEqualRegInstX("sqrdmulh", "SqrdmulhElemScX", "SimdMultOp",
225010037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqrdmulhCode, byElem=True,
225110037SARM gem5 Developers                       scalar=True)
225210037SARM gem5 Developers    # SQRDMULH (vector)
225310037SARM gem5 Developers    threeEqualRegInstX("sqrdmulh", "SqrdmulhDX", "SimdMultOp",
225410037SARM gem5 Developers                       ("int16_t", "int32_t"), 2, sqrdmulhCode)
225510037SARM gem5 Developers    threeEqualRegInstX("sqrdmulh", "SqrdmulhQX", "SimdMultOp",
225610037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqrdmulhCode)
225710037SARM gem5 Developers    threeEqualRegInstX("sqrdmulh", "SqrdmulhScX", "SimdMultOp",
225810037SARM gem5 Developers                       ("int16_t", "int32_t"), 4, sqrdmulhCode, scalar=True)
225910037SARM gem5 Developers    # SQRSHL
226010037SARM gem5 Developers    sqrshlCode = '''
226110037SARM gem5 Developers            int16_t shiftAmt = (int8_t)srcElem2;
226210037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
226310037SARM gem5 Developers            if (shiftAmt < 0) {
226410037SARM gem5 Developers                shiftAmt = -shiftAmt;
226510037SARM gem5 Developers                Element rBit = 0;
226610037SARM gem5 Developers                if (shiftAmt <= sizeof(Element) * 8)
226710037SARM gem5 Developers                    rBit = bits(srcElem1, shiftAmt - 1);
226810037SARM gem5 Developers                if (shiftAmt > sizeof(Element) * 8 && srcElem1 < 0)
226910037SARM gem5 Developers                    rBit = 1;
227010037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
227110037SARM gem5 Developers                    shiftAmt = sizeof(Element) * 8 - 1;
227210037SARM gem5 Developers                    destElem = 0;
227310037SARM gem5 Developers                } else {
227410037SARM gem5 Developers                    destElem = (srcElem1 >> shiftAmt);
227510037SARM gem5 Developers                }
227610037SARM gem5 Developers                // Make sure the right shift sign extended when it should.
227710037SARM gem5 Developers                if (srcElem1 < 0 && destElem >= 0) {
227810037SARM gem5 Developers                    destElem |= -((Element)1 << (sizeof(Element) * 8 -
227910037SARM gem5 Developers                                                 1 - shiftAmt));
228010037SARM gem5 Developers                }
228110037SARM gem5 Developers                destElem += rBit;
228210037SARM gem5 Developers            } else if (shiftAmt > 0) {
228310037SARM gem5 Developers                bool sat = false;
228410037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
228510037SARM gem5 Developers                    if (srcElem1 != 0)
228610037SARM gem5 Developers                        sat = true;
228710037SARM gem5 Developers                    else
228810037SARM gem5 Developers                        destElem = 0;
228910037SARM gem5 Developers                } else {
229010037SARM gem5 Developers                    if (bits((uint64_t) srcElem1, sizeof(Element) * 8 - 1,
229110037SARM gem5 Developers                                sizeof(Element) * 8 - 1 - shiftAmt) !=
229210037SARM gem5 Developers                            ((srcElem1 < 0) ? mask(shiftAmt + 1) : 0)) {
229310037SARM gem5 Developers                        sat = true;
229410037SARM gem5 Developers                    } else {
229510037SARM gem5 Developers                        destElem = srcElem1 << shiftAmt;
229610037SARM gem5 Developers                    }
229710037SARM gem5 Developers                }
229810037SARM gem5 Developers                if (sat) {
229910037SARM gem5 Developers                    fpscr.qc = 1;
230010037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8 - 1);
230110037SARM gem5 Developers                    if (srcElem1 < 0)
230210037SARM gem5 Developers                        destElem = ~destElem;
230310037SARM gem5 Developers                }
230410037SARM gem5 Developers            } else {
230510037SARM gem5 Developers                destElem = srcElem1;
230610037SARM gem5 Developers            }
230710037SARM gem5 Developers            FpscrQc = fpscr;
230810037SARM gem5 Developers    '''
230910037SARM gem5 Developers    threeEqualRegInstX("sqrshl", "SqrshlDX", "SimdCmpOp", smallSignedTypes, 2,
231010037SARM gem5 Developers                       sqrshlCode)
231110037SARM gem5 Developers    threeEqualRegInstX("sqrshl", "SqrshlQX", "SimdCmpOp", signedTypes, 4,
231210037SARM gem5 Developers                       sqrshlCode)
231310037SARM gem5 Developers    threeEqualRegInstX("sqrshl", "SqrshlScX", "SimdCmpOp", signedTypes, 4,
231410037SARM gem5 Developers                       sqrshlCode, scalar=True)
231510037SARM gem5 Developers    # SQRSHRN, SQRSHRN2
231610037SARM gem5 Developers    sqrshrnCode = '''
231710037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
231810037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
231910037SARM gem5 Developers                if (srcElem1 != 0 && srcElem1 != -1)
232010037SARM gem5 Developers                    fpscr.qc = 1;
232110037SARM gem5 Developers                destElem = 0;
232210037SARM gem5 Developers            } else if (imm) {
232310037SARM gem5 Developers                BigElement mid = (srcElem1 >> (imm - 1));
232410037SARM gem5 Developers                uint64_t rBit = mid & 0x1;
232510037SARM gem5 Developers                mid >>= 1;
232610037SARM gem5 Developers                mid |= -(mid & ((BigElement)1 <<
232710037SARM gem5 Developers                            (sizeof(BigElement) * 8 - 1 - imm)));
232810037SARM gem5 Developers                mid += rBit;
232910037SARM gem5 Developers                if (mid != (Element)mid) {
233010037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8 - 1);
233110037SARM gem5 Developers                    if (srcElem1 < 0)
233210037SARM gem5 Developers                        destElem = ~destElem;
233310037SARM gem5 Developers                    fpscr.qc = 1;
233410037SARM gem5 Developers                } else {
233510037SARM gem5 Developers                    destElem = mid;
233610037SARM gem5 Developers                }
233710037SARM gem5 Developers            } else {
233810037SARM gem5 Developers                if (srcElem1 != (Element)srcElem1) {
233910037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8 - 1);
234010037SARM gem5 Developers                    if (srcElem1 < 0)
234110037SARM gem5 Developers                        destElem = ~destElem;
234210037SARM gem5 Developers                    fpscr.qc = 1;
234310037SARM gem5 Developers                } else {
234410037SARM gem5 Developers                    destElem = srcElem1;
234510037SARM gem5 Developers                }
234610037SARM gem5 Developers            }
234710037SARM gem5 Developers            FpscrQc = fpscr;
234810037SARM gem5 Developers    '''
234910037SARM gem5 Developers    twoRegNarrowInstX("sqrshrn", "SqrshrnX", "SimdShiftOp", smallSignedTypes,
235010037SARM gem5 Developers                      sqrshrnCode, hasImm=True)
235110037SARM gem5 Developers    twoRegNarrowInstX("sqrshrn2", "Sqrshrn2X", "SimdShiftOp", smallSignedTypes,
235210037SARM gem5 Developers                      sqrshrnCode, hasImm=True, hi=True)
235310037SARM gem5 Developers    twoRegNarrowInstX("sqrshrn", "SqrshrnScX", "SimdShiftOp", smallSignedTypes,
235410037SARM gem5 Developers                      sqrshrnCode, hasImm=True, scalar=True)
235510037SARM gem5 Developers    # SQRSHRUN, SQRSHRUN2
235610037SARM gem5 Developers    sqrshrunCode = '''
235710037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
235810037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
235910037SARM gem5 Developers                if (srcElem1 != 0)
236010037SARM gem5 Developers                    fpscr.qc = 1;
236110037SARM gem5 Developers                destElem = 0;
236210037SARM gem5 Developers            } else if (imm) {
236310037SARM gem5 Developers                BigElement mid = (srcElem1 >> (imm - 1));
236410037SARM gem5 Developers                uint64_t rBit = mid & 0x1;
236510037SARM gem5 Developers                mid >>= 1;
236610037SARM gem5 Developers                mid |= -(mid & ((BigElement)1 <<
236710037SARM gem5 Developers                                (sizeof(BigElement) * 8 - 1 - imm)));
236810037SARM gem5 Developers                mid += rBit;
236910037SARM gem5 Developers                if (bits(mid, sizeof(BigElement) * 8 - 1,
237010037SARM gem5 Developers                              sizeof(Element) * 8) != 0) {
237110037SARM gem5 Developers                    if (srcElem1 < 0) {
237210037SARM gem5 Developers                        destElem = 0;
237310037SARM gem5 Developers                    } else {
237410037SARM gem5 Developers                        destElem = mask(sizeof(Element) * 8);
237510037SARM gem5 Developers                    }
237610037SARM gem5 Developers                    fpscr.qc = 1;
237710037SARM gem5 Developers                } else {
237810037SARM gem5 Developers                    destElem = mid;
237910037SARM gem5 Developers                }
238010037SARM gem5 Developers            } else {
238110037SARM gem5 Developers                if (srcElem1 < 0) {
238210037SARM gem5 Developers                    fpscr.qc = 1;
238310037SARM gem5 Developers                    destElem = 0;
238410037SARM gem5 Developers                } else {
238510037SARM gem5 Developers                    destElem = srcElem1;
238610037SARM gem5 Developers                }
238710037SARM gem5 Developers            }
238810037SARM gem5 Developers            FpscrQc = fpscr;
238910037SARM gem5 Developers    '''
239010037SARM gem5 Developers    twoRegNarrowInstX("sqrshrun", "SqrshrunX", "SimdShiftOp", smallSignedTypes,
239110037SARM gem5 Developers                      sqrshrunCode, hasImm=True)
239210037SARM gem5 Developers    twoRegNarrowInstX("sqrshrun", "Sqrshrun2X", "SimdShiftOp",
239310037SARM gem5 Developers                      smallSignedTypes, sqrshrunCode, hasImm=True, hi=True)
239410037SARM gem5 Developers    twoRegNarrowInstX("sqrshrun", "SqrshrunScX", "SimdShiftOp",
239510037SARM gem5 Developers                      smallSignedTypes, sqrshrunCode, hasImm=True, scalar=True)
239610037SARM gem5 Developers    # SQSHL (immediate)
239710037SARM gem5 Developers    sqshlImmCode = '''
239810037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
239910037SARM gem5 Developers            if (imm >= sizeof(Element) * 8) {
240010037SARM gem5 Developers                if (srcElem1 != 0) {
240112038Srekai.gonzalezalberquilla@arm.com                    destElem = std::numeric_limits<Element>::min();
240210037SARM gem5 Developers                    if (srcElem1 > 0)
240310037SARM gem5 Developers                        destElem = ~destElem;
240410037SARM gem5 Developers                    fpscr.qc = 1;
240510037SARM gem5 Developers                } else {
240610037SARM gem5 Developers                    destElem = 0;
240710037SARM gem5 Developers                }
240810037SARM gem5 Developers            } else if (imm) {
240910037SARM gem5 Developers                destElem = (srcElem1 << imm);
241010037SARM gem5 Developers                uint64_t topBits = bits((uint64_t)srcElem1,
241110037SARM gem5 Developers                                        sizeof(Element) * 8 - 1,
241210037SARM gem5 Developers                                        sizeof(Element) * 8 - 1 - imm);
241310037SARM gem5 Developers                if (topBits != 0 && topBits != mask(imm + 1)) {
241412038Srekai.gonzalezalberquilla@arm.com                    destElem = std::numeric_limits<Element>::min();
241510037SARM gem5 Developers                    if (srcElem1 > 0)
241610037SARM gem5 Developers                        destElem = ~destElem;
241710037SARM gem5 Developers                    fpscr.qc = 1;
241810037SARM gem5 Developers                }
241910037SARM gem5 Developers            } else {
242010037SARM gem5 Developers                destElem = srcElem1;
242110037SARM gem5 Developers            }
242210037SARM gem5 Developers            FpscrQc = fpscr;
242310037SARM gem5 Developers    '''
242410037SARM gem5 Developers    twoEqualRegInstX("sqshl", "SqshlImmDX", "SimdAluOp", smallSignedTypes, 2,
242510037SARM gem5 Developers                     sqshlImmCode, hasImm=True)
242610037SARM gem5 Developers    twoEqualRegInstX("sqshl", "SqshlImmQX", "SimdAluOp", signedTypes, 4,
242710037SARM gem5 Developers                     sqshlImmCode, hasImm=True)
242810037SARM gem5 Developers    twoEqualRegInstX("sqshl", "SqshlImmScX", "SimdAluOp", signedTypes, 4,
242910037SARM gem5 Developers                     sqshlImmCode, hasImm=True, scalar=True)
243010037SARM gem5 Developers    # SQSHL (register)
243110037SARM gem5 Developers    sqshlCode = '''
243210037SARM gem5 Developers            int16_t shiftAmt = (int8_t)srcElem2;
243310037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
243410037SARM gem5 Developers            if (shiftAmt < 0) {
243510037SARM gem5 Developers                shiftAmt = -shiftAmt;
243610037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
243710037SARM gem5 Developers                    shiftAmt = sizeof(Element) * 8 - 1;
243810037SARM gem5 Developers                    destElem = 0;
243910037SARM gem5 Developers                } else {
244010037SARM gem5 Developers                    destElem = (srcElem1 >> shiftAmt);
244110037SARM gem5 Developers                }
244210037SARM gem5 Developers                // Make sure the right shift sign extended when it should.
244310037SARM gem5 Developers                if (srcElem1 < 0 && destElem >= 0) {
244410037SARM gem5 Developers                    destElem |= -((Element)1 << (sizeof(Element) * 8 -
244510037SARM gem5 Developers                                                 1 - shiftAmt));
244610037SARM gem5 Developers                }
244710037SARM gem5 Developers            } else if (shiftAmt > 0) {
244810037SARM gem5 Developers                bool sat = false;
244910037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
245010037SARM gem5 Developers                    if (srcElem1 != 0)
245110037SARM gem5 Developers                        sat = true;
245210037SARM gem5 Developers                    else
245310037SARM gem5 Developers                        destElem = 0;
245410037SARM gem5 Developers                } else {
245510037SARM gem5 Developers                    if (bits((uint64_t) srcElem1, sizeof(Element) * 8 - 1,
245610037SARM gem5 Developers                                sizeof(Element) * 8 - 1 - shiftAmt) !=
245710037SARM gem5 Developers                            ((srcElem1 < 0) ? mask(shiftAmt + 1) : 0)) {
245810037SARM gem5 Developers                        sat = true;
245910037SARM gem5 Developers                    } else {
246010037SARM gem5 Developers                        destElem = srcElem1 << shiftAmt;
246110037SARM gem5 Developers                    }
246210037SARM gem5 Developers                }
246310037SARM gem5 Developers                if (sat) {
246410037SARM gem5 Developers                    fpscr.qc = 1;
246510037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8 - 1);
246610037SARM gem5 Developers                    if (srcElem1 < 0)
246710037SARM gem5 Developers                        destElem = ~destElem;
246810037SARM gem5 Developers                }
246910037SARM gem5 Developers            } else {
247010037SARM gem5 Developers                destElem = srcElem1;
247110037SARM gem5 Developers            }
247210037SARM gem5 Developers            FpscrQc = fpscr;
247310037SARM gem5 Developers    '''
247410037SARM gem5 Developers    threeEqualRegInstX("sqshl", "SqshlDX", "SimdAluOp", smallSignedTypes, 2,
247510037SARM gem5 Developers                       sqshlCode)
247610037SARM gem5 Developers    threeEqualRegInstX("sqshl", "SqshlQX", "SimdAluOp", signedTypes, 4,
247710037SARM gem5 Developers                       sqshlCode)
247810037SARM gem5 Developers    threeEqualRegInstX("sqshl", "SqshlScX", "SimdAluOp", signedTypes, 4,
247910037SARM gem5 Developers                       sqshlCode, scalar=True)
248010037SARM gem5 Developers    # SQSHLU
248110037SARM gem5 Developers    sqshluCode = '''
248210037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
248310037SARM gem5 Developers            if (imm >= sizeof(Element) * 8) {
248410037SARM gem5 Developers                if (srcElem1 < 0) {
248510037SARM gem5 Developers                    destElem = 0;
248610037SARM gem5 Developers                    fpscr.qc = 1;
248710037SARM gem5 Developers                } else if (srcElem1 > 0) {
248810037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8);
248910037SARM gem5 Developers                    fpscr.qc = 1;
249010037SARM gem5 Developers                } else {
249110037SARM gem5 Developers                    destElem = 0;
249210037SARM gem5 Developers                }
249310037SARM gem5 Developers            } else if (imm) {
249410037SARM gem5 Developers                destElem = (srcElem1 << imm);
249510037SARM gem5 Developers                uint64_t topBits = bits((uint64_t)srcElem1,
249610037SARM gem5 Developers                                        sizeof(Element) * 8 - 1,
249710037SARM gem5 Developers                                        sizeof(Element) * 8 - imm);
249810037SARM gem5 Developers                if (srcElem1 < 0) {
249910037SARM gem5 Developers                    destElem = 0;
250010037SARM gem5 Developers                    fpscr.qc = 1;
250110037SARM gem5 Developers                } else if (topBits != 0) {
250210037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8);
250310037SARM gem5 Developers                    fpscr.qc = 1;
250410037SARM gem5 Developers                }
250510037SARM gem5 Developers            } else {
250610037SARM gem5 Developers                if (srcElem1 < 0) {
250710037SARM gem5 Developers                    fpscr.qc = 1;
250810037SARM gem5 Developers                    destElem = 0;
250910037SARM gem5 Developers                } else {
251010037SARM gem5 Developers                    destElem = srcElem1;
251110037SARM gem5 Developers                }
251210037SARM gem5 Developers            }
251310037SARM gem5 Developers            FpscrQc = fpscr;
251410037SARM gem5 Developers    '''
251510037SARM gem5 Developers    twoEqualRegInstX("sqshlu", "SqshluDX", "SimdAluOp", smallSignedTypes, 2,
251610037SARM gem5 Developers                     sqshluCode, hasImm=True)
251710037SARM gem5 Developers    twoEqualRegInstX("sqshlu", "SqshluQX", "SimdAluOp", signedTypes, 4,
251810037SARM gem5 Developers                     sqshluCode, hasImm=True)
251910037SARM gem5 Developers    twoEqualRegInstX("sqshlu", "SqshluScX", "SimdAluOp", signedTypes, 4,
252010037SARM gem5 Developers                     sqshluCode, hasImm=True, scalar=True)
252110037SARM gem5 Developers    # SQSHRN, SQSHRN2
252210037SARM gem5 Developers    sqshrnCode = '''
252310037SARM gem5 Developers        FPSCR fpscr = (FPSCR) FpscrQc;
252410037SARM gem5 Developers        if (imm > sizeof(srcElem1) * 8) {
252510037SARM gem5 Developers            if (srcElem1 != 0 && srcElem1 != -1)
252610037SARM gem5 Developers                fpscr.qc = 1;
252710037SARM gem5 Developers            destElem = 0;
252810037SARM gem5 Developers        } else if (imm) {
252910037SARM gem5 Developers            BigElement mid = ((srcElem1 >> (imm - 1)) >> 1);
253010037SARM gem5 Developers            mid |= -(mid & ((BigElement)1 <<
253110037SARM gem5 Developers                        (sizeof(BigElement) * 8 - 1 - imm)));
253210037SARM gem5 Developers            if (mid != (Element)mid) {
253310037SARM gem5 Developers                destElem = mask(sizeof(Element) * 8 - 1);
253410037SARM gem5 Developers                if (srcElem1 < 0)
253510037SARM gem5 Developers                    destElem = ~destElem;
253610037SARM gem5 Developers                fpscr.qc = 1;
253710037SARM gem5 Developers            } else {
253810037SARM gem5 Developers                destElem = mid;
253910037SARM gem5 Developers            }
254010037SARM gem5 Developers        } else {
254110037SARM gem5 Developers            destElem = srcElem1;
254210037SARM gem5 Developers        }
254310037SARM gem5 Developers        FpscrQc = fpscr;
254410037SARM gem5 Developers    '''
254510037SARM gem5 Developers    twoRegNarrowInstX("sqshrn", "SqshrnX", "SimdShiftOp", smallSignedTypes,
254610037SARM gem5 Developers                      sqshrnCode, hasImm=True)
254710037SARM gem5 Developers    twoRegNarrowInstX("sqshrn2", "Sqshrn2X", "SimdShiftOp", smallSignedTypes,
254810037SARM gem5 Developers                      sqshrnCode, hasImm=True, hi=True)
254910037SARM gem5 Developers    twoRegNarrowInstX("sqshrn", "SqshrnScX", "SimdShiftOp", smallSignedTypes,
255010037SARM gem5 Developers                      sqshrnCode, hasImm=True, scalar=True)
255110037SARM gem5 Developers    # SQSHRUN, SQSHRUN2
255210037SARM gem5 Developers    sqshrunCode = '''
255310037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
255410037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
255510037SARM gem5 Developers                if (srcElem1 != 0)
255610037SARM gem5 Developers                    fpscr.qc = 1;
255710037SARM gem5 Developers                destElem = 0;
255810037SARM gem5 Developers            } else if (imm) {
255910037SARM gem5 Developers                BigElement mid = ((srcElem1 >> (imm - 1)) >> 1);
256010037SARM gem5 Developers                if (bits(mid, sizeof(BigElement) * 8 - 1,
256110037SARM gem5 Developers                              sizeof(Element) * 8) != 0) {
256210037SARM gem5 Developers                    if (srcElem1 < 0) {
256310037SARM gem5 Developers                        destElem = 0;
256410037SARM gem5 Developers                    } else {
256510037SARM gem5 Developers                        destElem = mask(sizeof(Element) * 8);
256610037SARM gem5 Developers                    }
256710037SARM gem5 Developers                    fpscr.qc = 1;
256810037SARM gem5 Developers                } else {
256910037SARM gem5 Developers                    destElem = mid;
257010037SARM gem5 Developers                }
257110037SARM gem5 Developers            } else {
257210037SARM gem5 Developers                destElem = srcElem1;
257310037SARM gem5 Developers            }
257410037SARM gem5 Developers            FpscrQc = fpscr;
257510037SARM gem5 Developers    '''
257610037SARM gem5 Developers    twoRegNarrowInstX("sqshrun", "SqshrunX", "SimdShiftOp", smallSignedTypes,
257710037SARM gem5 Developers                      sqshrunCode, hasImm=True)
257810037SARM gem5 Developers    twoRegNarrowInstX("sqshrun", "Sqshrun2X", "SimdShiftOp", smallSignedTypes,
257910037SARM gem5 Developers                      sqshrunCode, hasImm=True, hi=True)
258010037SARM gem5 Developers    twoRegNarrowInstX("sqshrun", "SqshrunScX", "SimdShiftOp", smallSignedTypes,
258110037SARM gem5 Developers                      sqshrunCode, hasImm=True, scalar=True)
258210037SARM gem5 Developers    # SQSUB
258310037SARM gem5 Developers    sqsubCode = '''
258410037SARM gem5 Developers            destElem = srcElem1 - srcElem2;
258510037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
258610037SARM gem5 Developers            bool negDest = (destElem < 0);
258710037SARM gem5 Developers            bool negSrc1 = (srcElem1 < 0);
258810037SARM gem5 Developers            bool posSrc2 = (srcElem2 >= 0);
258910037SARM gem5 Developers            if ((negDest != negSrc1) && (negSrc1 == posSrc2)) {
259012038Srekai.gonzalezalberquilla@arm.com                destElem = std::numeric_limits<Element>::min();
259110037SARM gem5 Developers                if (negDest)
259210037SARM gem5 Developers                    destElem -= 1;
259310037SARM gem5 Developers                fpscr.qc = 1;
259410037SARM gem5 Developers            }
259510037SARM gem5 Developers            FpscrQc = fpscr;
259610037SARM gem5 Developers    '''
259710037SARM gem5 Developers    threeEqualRegInstX("sqsub", "SqsubDX", "SimdAddOp", smallSignedTypes, 2,
259810037SARM gem5 Developers                       sqsubCode)
259910037SARM gem5 Developers    threeEqualRegInstX("sqsub", "SqsubQX", "SimdAddOp", signedTypes, 4,
260010037SARM gem5 Developers                       sqsubCode)
260110037SARM gem5 Developers    threeEqualRegInstX("sqsub", "SqsubScX", "SimdAddOp", signedTypes, 4,
260210037SARM gem5 Developers                       sqsubCode, scalar=True)
260310037SARM gem5 Developers    # SQXTN, SQXTN2
260410037SARM gem5 Developers    sqxtnCode = '''
260510037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
260610037SARM gem5 Developers            destElem = srcElem1;
260710037SARM gem5 Developers            if ((BigElement)destElem != srcElem1) {
260810037SARM gem5 Developers                fpscr.qc = 1;
260910037SARM gem5 Developers                destElem = mask(sizeof(Element) * 8 - 1);
261010037SARM gem5 Developers                if (srcElem1 < 0)
261110037SARM gem5 Developers                    destElem = ~destElem;
261210037SARM gem5 Developers            }
261310037SARM gem5 Developers            FpscrQc = fpscr;
261410037SARM gem5 Developers    '''
261510037SARM gem5 Developers    twoRegNarrowInstX("sqxtn", "SqxtnX", "SimdMiscOp", smallSignedTypes,
261610037SARM gem5 Developers                      sqxtnCode)
261710037SARM gem5 Developers    twoRegNarrowInstX("sqxtn", "Sqxtn2X", "SimdMiscOp", smallSignedTypes,
261810037SARM gem5 Developers                      sqxtnCode, hi=True)
261910037SARM gem5 Developers    twoRegNarrowInstX("sqxtn", "SqxtnScX", "SimdMiscOp", smallSignedTypes,
262010037SARM gem5 Developers                      sqxtnCode, scalar=True)
262110037SARM gem5 Developers    # SQXTUN, SQXTUN2
262210037SARM gem5 Developers    sqxtunCode = '''
262310037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
262410037SARM gem5 Developers            destElem = srcElem1;
262510037SARM gem5 Developers            if (srcElem1 < 0 ||
262610037SARM gem5 Developers                    ((BigElement)destElem & mask(sizeof(Element) * 8)) != srcElem1) {
262710037SARM gem5 Developers                fpscr.qc = 1;
262810037SARM gem5 Developers                destElem = mask(sizeof(Element) * 8);
262910037SARM gem5 Developers                if (srcElem1 < 0)
263010037SARM gem5 Developers                    destElem = ~destElem;
263110037SARM gem5 Developers            }
263210037SARM gem5 Developers            FpscrQc = fpscr;
263310037SARM gem5 Developers    '''
263410037SARM gem5 Developers    twoRegNarrowInstX("sqxtun", "SqxtunX", "SimdMiscOp", smallSignedTypes,
263510037SARM gem5 Developers                      sqxtunCode)
263610037SARM gem5 Developers    twoRegNarrowInstX("sqxtun", "Sqxtun2X", "SimdMiscOp", smallSignedTypes,
263710037SARM gem5 Developers                      sqxtunCode, hi=True)
263810037SARM gem5 Developers    twoRegNarrowInstX("sqxtun", "SqxtunScX", "SimdMiscOp", smallSignedTypes,
263910037SARM gem5 Developers                      sqxtunCode, scalar=True)
264010037SARM gem5 Developers    # SRHADD
264110037SARM gem5 Developers    rhaddCode = '''
264210037SARM gem5 Developers            Element carryBit =
264310037SARM gem5 Developers                (((unsigned)srcElem1 & 0x1) +
264410037SARM gem5 Developers                 ((unsigned)srcElem2 & 0x1) + 1) >> 1;
264510037SARM gem5 Developers            // Use division instead of a shift to ensure the sign extension works
264610037SARM gem5 Developers            // right. The compiler will figure out if it can be a shift. Mask the
264710037SARM gem5 Developers            // inputs so they get truncated correctly.
264810037SARM gem5 Developers            destElem = (((srcElem1 & ~(Element)1) / 2) +
264910037SARM gem5 Developers                        ((srcElem2 & ~(Element)1) / 2)) + carryBit;
265010037SARM gem5 Developers    '''
265110037SARM gem5 Developers    threeEqualRegInstX("srhadd", "SrhaddDX", "SimdAddOp", smallSignedTypes, 2,
265210037SARM gem5 Developers                       rhaddCode)
265310037SARM gem5 Developers    threeEqualRegInstX("srhadd", "SrhaddQX", "SimdAddOp", smallSignedTypes, 4,
265410037SARM gem5 Developers                       rhaddCode)
265510037SARM gem5 Developers    # SRI
265610037SARM gem5 Developers    sriCode = '''
265710037SARM gem5 Developers            if (imm >= sizeof(Element) * 8)
265810037SARM gem5 Developers                destElem = destElem;
265910037SARM gem5 Developers            else
266010037SARM gem5 Developers                destElem = (srcElem1 >> imm) |
266110037SARM gem5 Developers                    (destElem & ~mask(sizeof(Element) * 8 - imm));
266210037SARM gem5 Developers    '''
266310037SARM gem5 Developers    twoEqualRegInstX("sri", "SriDX", "SimdShiftOp", unsignedTypes, 2, sriCode,
266410037SARM gem5 Developers                     True, hasImm=True)
266510037SARM gem5 Developers    twoEqualRegInstX("sri", "SriQX", "SimdShiftOp", unsignedTypes, 4, sriCode,
266610037SARM gem5 Developers                     True, hasImm=True)
266710037SARM gem5 Developers    # SRSHL
266810037SARM gem5 Developers    rshlCode = '''
266910037SARM gem5 Developers            int16_t shiftAmt = (int8_t)srcElem2;
267010037SARM gem5 Developers            if (shiftAmt < 0) {
267110037SARM gem5 Developers                shiftAmt = -shiftAmt;
267210037SARM gem5 Developers                Element rBit = 0;
267310037SARM gem5 Developers                if (shiftAmt <= sizeof(Element) * 8)
267410037SARM gem5 Developers                    rBit = bits(srcElem1, shiftAmt - 1);
267510037SARM gem5 Developers                if (shiftAmt > sizeof(Element) * 8 && ltz(srcElem1))
267610037SARM gem5 Developers                    rBit = 1;
267710037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
267810037SARM gem5 Developers                    shiftAmt = sizeof(Element) * 8 - 1;
267910037SARM gem5 Developers                    destElem = 0;
268010037SARM gem5 Developers                } else {
268110037SARM gem5 Developers                    destElem = (srcElem1 >> shiftAmt);
268210037SARM gem5 Developers                }
268310037SARM gem5 Developers                // Make sure the right shift sign extended when it should.
268410037SARM gem5 Developers                if (ltz(srcElem1) && !ltz(destElem)) {
268510037SARM gem5 Developers                    destElem |= -((Element)1 << (sizeof(Element) * 8 -
268610037SARM gem5 Developers                                                 1 - shiftAmt));
268710037SARM gem5 Developers                }
268810037SARM gem5 Developers                destElem += rBit;
268910037SARM gem5 Developers            } else if (shiftAmt > 0) {
269010037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
269110037SARM gem5 Developers                    destElem = 0;
269210037SARM gem5 Developers                } else {
269310037SARM gem5 Developers                    destElem = srcElem1 << shiftAmt;
269410037SARM gem5 Developers                }
269510037SARM gem5 Developers            } else {
269610037SARM gem5 Developers                destElem = srcElem1;
269710037SARM gem5 Developers            }
269810037SARM gem5 Developers    '''
269910037SARM gem5 Developers    threeEqualRegInstX("srshl", "SrshlDX", "SimdShiftOp", signedTypes, 2,
270010037SARM gem5 Developers                       rshlCode)
270110037SARM gem5 Developers    threeEqualRegInstX("srshl", "SrshlQX", "SimdShiftOp", signedTypes, 4,
270210037SARM gem5 Developers                       rshlCode)
270310037SARM gem5 Developers    # SRSHR
270410037SARM gem5 Developers    rshrCode = '''
270510037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
270610037SARM gem5 Developers                destElem = 0;
270710037SARM gem5 Developers            } else if (imm) {
270810037SARM gem5 Developers                Element rBit = bits(srcElem1, imm - 1);
270910037SARM gem5 Developers                destElem = ((srcElem1 >> (imm - 1)) >> 1) + rBit;
271010037SARM gem5 Developers            } else {
271110037SARM gem5 Developers                destElem = srcElem1;
271210037SARM gem5 Developers            }
271310037SARM gem5 Developers    '''
271410037SARM gem5 Developers    twoEqualRegInstX("srshr", "SrshrDX", "SimdShiftOp", signedTypes, 2,
271510037SARM gem5 Developers                     rshrCode, hasImm=True)
271610037SARM gem5 Developers    twoEqualRegInstX("srshr", "SrshrQX", "SimdShiftOp", signedTypes, 4,
271710037SARM gem5 Developers                     rshrCode, hasImm=True)
271810037SARM gem5 Developers    # SRSRA
271910037SARM gem5 Developers    rsraCode = '''
272010037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
272110037SARM gem5 Developers                destElem += 0;
272210037SARM gem5 Developers            } else if (imm) {
272310037SARM gem5 Developers                Element rBit = bits(srcElem1, imm - 1);
272410037SARM gem5 Developers                destElem += ((srcElem1 >> (imm - 1)) >> 1) + rBit;
272510037SARM gem5 Developers            } else {
272610037SARM gem5 Developers                destElem += srcElem1;
272710037SARM gem5 Developers            }
272810037SARM gem5 Developers    '''
272910037SARM gem5 Developers    twoEqualRegInstX("srsra", "SrsraDX", "SimdShiftOp", signedTypes, 2,
273010037SARM gem5 Developers                     rsraCode, True, hasImm=True)
273110037SARM gem5 Developers    twoEqualRegInstX("srsra", "SrsraQX", "SimdShiftOp", signedTypes, 4,
273210037SARM gem5 Developers                     rsraCode, True, hasImm=True)
273310037SARM gem5 Developers    # SSHL
273410037SARM gem5 Developers    shlCode = '''
273510037SARM gem5 Developers            int16_t shiftAmt = (int8_t)srcElem2;
273610037SARM gem5 Developers            if (shiftAmt < 0) {
273710037SARM gem5 Developers                shiftAmt = -shiftAmt;
273810037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
273910037SARM gem5 Developers                    shiftAmt = sizeof(Element) * 8 - 1;
274010037SARM gem5 Developers                    destElem = 0;
274110037SARM gem5 Developers                } else {
274210037SARM gem5 Developers                    destElem = (srcElem1 >> shiftAmt);
274310037SARM gem5 Developers                }
274410037SARM gem5 Developers                // Make sure the right shift sign extended when it should.
274510037SARM gem5 Developers                if (ltz(srcElem1) && !ltz(destElem)) {
274610037SARM gem5 Developers                    destElem |= -((Element)1 << (sizeof(Element) * 8 -
274710037SARM gem5 Developers                                                 1 - shiftAmt));
274810037SARM gem5 Developers                }
274910037SARM gem5 Developers            } else {
275010037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
275110037SARM gem5 Developers                    destElem = 0;
275210037SARM gem5 Developers                } else {
275310037SARM gem5 Developers                    destElem = srcElem1 << shiftAmt;
275410037SARM gem5 Developers                }
275510037SARM gem5 Developers            }
275610037SARM gem5 Developers    '''
275710037SARM gem5 Developers    threeEqualRegInstX("sshl", "SshlDX", "SimdShiftOp", signedTypes, 2,
275810037SARM gem5 Developers                       shlCode)
275910037SARM gem5 Developers    threeEqualRegInstX("sshl", "SshlQX", "SimdShiftOp", signedTypes, 4,
276010037SARM gem5 Developers                       shlCode)
276110037SARM gem5 Developers    # SSHLL, SSHLL2
276210037SARM gem5 Developers    shllCode = '''
276310037SARM gem5 Developers            if (imm >= sizeof(destElem) * 8) {
276410037SARM gem5 Developers                destElem = 0;
276510037SARM gem5 Developers            } else {
276610037SARM gem5 Developers                destElem = (BigElement)srcElem1 << imm;
276710037SARM gem5 Developers            }
276810037SARM gem5 Developers    '''
276910037SARM gem5 Developers    twoRegLongInstX("sshll", "SshllX", "SimdShiftOp", smallSignedTypes,
277010037SARM gem5 Developers                    shllCode, hasImm=True)
277110037SARM gem5 Developers    twoRegLongInstX("sshll", "Sshll2X", "SimdShiftOp", smallSignedTypes,
277210037SARM gem5 Developers                    shllCode, hasImm=True, hi=True)
277310037SARM gem5 Developers    # SSHR
277410037SARM gem5 Developers    shrCode = '''
277510037SARM gem5 Developers            if (imm >= sizeof(srcElem1) * 8) {
277610037SARM gem5 Developers                if (ltz(srcElem1))
277710037SARM gem5 Developers                    destElem = -1;
277810037SARM gem5 Developers                else
277910037SARM gem5 Developers                    destElem = 0;
278010037SARM gem5 Developers            } else {
278110037SARM gem5 Developers                destElem = srcElem1 >> imm;
278210037SARM gem5 Developers            }
278310037SARM gem5 Developers    '''
278410037SARM gem5 Developers    twoEqualRegInstX("sshr", "SshrDX", "SimdShiftOp", signedTypes, 2, shrCode,
278510037SARM gem5 Developers                     hasImm=True)
278610037SARM gem5 Developers    twoEqualRegInstX("sshr", "SshrQX", "SimdShiftOp", signedTypes, 4, shrCode,
278710037SARM gem5 Developers                     hasImm=True)
278810037SARM gem5 Developers    # SSRA
278910037SARM gem5 Developers    sraCode = '''
279010037SARM gem5 Developers            Element mid;;
279110037SARM gem5 Developers            if (imm >= sizeof(srcElem1) * 8) {
279210037SARM gem5 Developers                mid = ltz(srcElem1) ? -1 : 0;
279310037SARM gem5 Developers            } else {
279410037SARM gem5 Developers                mid = srcElem1 >> imm;
279510037SARM gem5 Developers                if (ltz(srcElem1) && !ltz(mid)) {
279610037SARM gem5 Developers                    mid |= -(mid & ((Element)1 <<
279710037SARM gem5 Developers                                    (sizeof(Element) * 8 - 1 - imm)));
279810037SARM gem5 Developers                }
279910037SARM gem5 Developers            }
280010037SARM gem5 Developers            destElem += mid;
280110037SARM gem5 Developers    '''
280210037SARM gem5 Developers    twoEqualRegInstX("ssra", "SsraDX", "SimdShiftOp", signedTypes, 2, sraCode,
280310037SARM gem5 Developers                     True, hasImm=True)
280410037SARM gem5 Developers    twoEqualRegInstX("ssra", "SsraQX", "SimdShiftOp", signedTypes, 4, sraCode,
280510037SARM gem5 Developers                     True, hasImm=True)
280610037SARM gem5 Developers    # SSUBL
280710037SARM gem5 Developers    sublwCode = "destElem = (BigElement)srcElem1 - (BigElement)srcElem2;"
280810037SARM gem5 Developers    threeRegLongInstX("ssubl", "SsublX", "SimdAddOp", smallSignedTypes,
280910037SARM gem5 Developers                      sublwCode)
281010037SARM gem5 Developers    threeRegLongInstX("ssubl2", "Ssubl2X", "SimdAddOp", smallSignedTypes,
281110037SARM gem5 Developers                      sublwCode, hi=True)
281210037SARM gem5 Developers    # SSUBW
281310037SARM gem5 Developers    threeRegWideInstX("ssubw", "SsubwX", "SimdAddOp", smallSignedTypes,
281410037SARM gem5 Developers                      sublwCode)
281510037SARM gem5 Developers    threeRegWideInstX("ssubw2", "Ssubw2X", "SimdAddOp", smallSignedTypes,
281610037SARM gem5 Developers                      sublwCode, hi=True)
281710037SARM gem5 Developers    # SUB
281810037SARM gem5 Developers    subCode = "destElem = srcElem1 - srcElem2;"
281910037SARM gem5 Developers    threeEqualRegInstX("sub", "SubDX", "SimdAddOp", unsignedTypes, 2, subCode)
282010037SARM gem5 Developers    threeEqualRegInstX("sub", "SubQX", "SimdAddOp", unsignedTypes, 4, subCode)
282110037SARM gem5 Developers    # SUBHN, SUBHN2
282210037SARM gem5 Developers    subhnCode = '''
282310037SARM gem5 Developers            destElem = ((BigElement)srcElem1 - (BigElement)srcElem2) >>
282410037SARM gem5 Developers                        (sizeof(Element) * 8);
282510037SARM gem5 Developers    '''
282610037SARM gem5 Developers    threeRegNarrowInstX("subhn", "SubhnX", "SimdAddOp", smallUnsignedTypes,
282710037SARM gem5 Developers                        subhnCode)
282810037SARM gem5 Developers    threeRegNarrowInstX("subhn2", "Subhn2X", "SimdAddOp", smallUnsignedTypes,
282910037SARM gem5 Developers                        subhnCode, hi=True)
283010037SARM gem5 Developers    # SUQADD
283110037SARM gem5 Developers    suqaddCode = '''
283210037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
283310037SARM gem5 Developers            Element tmp = destElem + srcElem1;
283410037SARM gem5 Developers            if (bits(destElem, sizeof(Element) * 8 - 1) == 0) {
283510037SARM gem5 Developers                if (bits(tmp, sizeof(Element) * 8 - 1) == 1 ||
283610037SARM gem5 Developers                        tmp < srcElem1 || tmp < destElem) {
283710037SARM gem5 Developers                    destElem = (((Element) 1) << (sizeof(Element) * 8 - 1)) - 1;
283810037SARM gem5 Developers                    fpscr.qc = 1;
283910037SARM gem5 Developers                } else {
284010037SARM gem5 Developers                    destElem = tmp;
284110037SARM gem5 Developers                }
284210037SARM gem5 Developers            } else {
284310037SARM gem5 Developers                Element absDestElem = (~destElem) + 1;
284410037SARM gem5 Developers                if (absDestElem < srcElem1) {
284510037SARM gem5 Developers                    // Still check for positive sat., no need to check for negative sat.
284610037SARM gem5 Developers                    if (bits(tmp, sizeof(Element) * 8 - 1) == 1) {
284710037SARM gem5 Developers                        destElem = (((Element) 1) << (sizeof(Element) * 8 - 1)) - 1;
284810037SARM gem5 Developers                        fpscr.qc = 1;
284910037SARM gem5 Developers                    } else {
285010037SARM gem5 Developers                        destElem = tmp;
285110037SARM gem5 Developers                    }
285210037SARM gem5 Developers                } else {
285310037SARM gem5 Developers                    destElem = tmp;
285410037SARM gem5 Developers                }
285510037SARM gem5 Developers            }
285610037SARM gem5 Developers            FpscrQc = fpscr;
285710037SARM gem5 Developers    '''
285810037SARM gem5 Developers    twoEqualRegInstX("suqadd", "SuqaddDX", "SimdAddOp", smallUnsignedTypes, 2,
285910037SARM gem5 Developers                     suqaddCode, True)
286010037SARM gem5 Developers    twoEqualRegInstX("suqadd", "SuqaddQX", "SimdAddOp", unsignedTypes, 4,
286110037SARM gem5 Developers                     suqaddCode, True)
286210037SARM gem5 Developers    twoEqualRegInstX("suqadd", "SuqaddScX", "SimdAddOp", unsignedTypes, 4,
286310037SARM gem5 Developers                     suqaddCode, True, scalar=True)
286410037SARM gem5 Developers    # SXTL -> alias to SSHLL
286510037SARM gem5 Developers    # TBL
286610037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl1DX", "SimdMiscOp", ("uint8_t",), 1, "true", 2)
286710037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl1QX", "SimdMiscOp", ("uint8_t",), 1, "true", 4)
286810037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl2DX", "SimdMiscOp", ("uint8_t",), 2, "true", 2)
286910037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl2QX", "SimdMiscOp", ("uint8_t",), 2, "true", 4)
287010037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl3DX", "SimdMiscOp", ("uint8_t",), 3, "true", 2)
287110037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl3QX", "SimdMiscOp", ("uint8_t",), 3, "true", 4)
287210037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl4DX", "SimdMiscOp", ("uint8_t",), 4, "true", 2)
287310037SARM gem5 Developers    tbxTblInstX("tbl", "Tbl4QX", "SimdMiscOp", ("uint8_t",), 4, "true", 4)
287410037SARM gem5 Developers    # TBX
287510037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx1DX", "SimdMiscOp", ("uint8_t",), 1, "false", 2)
287610037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx1QX", "SimdMiscOp", ("uint8_t",), 1, "false", 4)
287710037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx2DX", "SimdMiscOp", ("uint8_t",), 2, "false", 2)
287810037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx2QX", "SimdMiscOp", ("uint8_t",), 2, "false", 4)
287910037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx3DX", "SimdMiscOp", ("uint8_t",), 3, "false", 2)
288010037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx3QX", "SimdMiscOp", ("uint8_t",), 3, "false", 4)
288110037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx4DX", "SimdMiscOp", ("uint8_t",), 4, "false", 2)
288210037SARM gem5 Developers    tbxTblInstX("tbx", "Tbx4QX", "SimdMiscOp", ("uint8_t",), 4, "false", 4)
288310037SARM gem5 Developers    # TRN1
288410037SARM gem5 Developers    trnCode = '''
288510037SARM gem5 Developers        unsigned part = %s;
288610037SARM gem5 Developers        for (unsigned i = 0; i < eCount / 2; i++) {
288710037SARM gem5 Developers            destReg.elements[2 * i] = srcReg1.elements[2 * i + part];
288810037SARM gem5 Developers            destReg.elements[2 * i + 1] = srcReg2.elements[2 * i + part];
288910037SARM gem5 Developers        }
289010037SARM gem5 Developers    '''
289110037SARM gem5 Developers    threeRegScrambleInstX("trn1", "Trn1DX", "SimdAluOp", smallUnsignedTypes, 2,
289210037SARM gem5 Developers                          trnCode % "0")
289310037SARM gem5 Developers    threeRegScrambleInstX("trn1", "Trn1QX", "SimdAluOp", unsignedTypes, 4,
289410037SARM gem5 Developers                          trnCode % "0")
289510037SARM gem5 Developers    # TRN2
289610037SARM gem5 Developers    threeRegScrambleInstX("trn2", "Trn2DX", "SimdAluOp", smallUnsignedTypes, 2,
289710037SARM gem5 Developers                          trnCode % "1")
289810037SARM gem5 Developers    threeRegScrambleInstX("trn2", "Trn2QX", "SimdAluOp", unsignedTypes, 4,
289910037SARM gem5 Developers                          trnCode % "1")
290010037SARM gem5 Developers    # UABA
290110037SARM gem5 Developers    threeEqualRegInstX("uaba", "UabaDX", "SimdAddAccOp", smallUnsignedTypes, 2,
290210037SARM gem5 Developers                       abaCode, True)
290310037SARM gem5 Developers    threeEqualRegInstX("uaba", "UabaQX", "SimdAddAccOp", smallUnsignedTypes, 4,
290410037SARM gem5 Developers                       abaCode, True)
290510037SARM gem5 Developers    # UABAL, UABAL2
290610037SARM gem5 Developers    threeRegLongInstX("uabal", "UabalX", "SimdAddAccOp", smallUnsignedTypes,
290710037SARM gem5 Developers                      abalCode, True)
290810037SARM gem5 Developers    threeRegLongInstX("uabal2", "Uabal2X", "SimdAddAccOp", smallUnsignedTypes,
290910037SARM gem5 Developers                      abalCode, True, hi=True)
291010037SARM gem5 Developers    # UABD
291110037SARM gem5 Developers    threeEqualRegInstX("uabd", "UabdDX", "SimdAddOp", smallUnsignedTypes, 2,
291210037SARM gem5 Developers                       abdCode)
291310037SARM gem5 Developers    threeEqualRegInstX("uabd", "UabdQX", "SimdAddOp", smallUnsignedTypes, 4,
291410037SARM gem5 Developers                       abdCode)
291510037SARM gem5 Developers    # UABDL, UABDL2
291610037SARM gem5 Developers    threeRegLongInstX("uabdl", "UabdlX", "SimdAddAccOp", smallUnsignedTypes,
291710037SARM gem5 Developers                      abdlCode, True)
291810037SARM gem5 Developers    threeRegLongInstX("uabdl2", "Uabdl2X", "SimdAddAccOp", smallUnsignedTypes,
291910037SARM gem5 Developers                      abdlCode, True, hi=True)
292010037SARM gem5 Developers    # UADALP
292110037SARM gem5 Developers    twoRegCondenseInstX("uadalp", "UadalpDX", "SimdAddOp", smallUnsignedTypes,
292210037SARM gem5 Developers                        2, adalpCode, True)
292310037SARM gem5 Developers    twoRegCondenseInstX("uadalp", "UadalpQX", "SimdAddOp", smallUnsignedTypes,
292410037SARM gem5 Developers                        4, adalpCode, True)
292510037SARM gem5 Developers    # UADDL, UADDL2
292610037SARM gem5 Developers    threeRegLongInstX("uaddl", "UaddlX", "SimdAddAccOp", smallUnsignedTypes,
292710037SARM gem5 Developers                      addlwCode)
292810037SARM gem5 Developers    threeRegLongInstX("uaddl2", "Uaddl2X", "SimdAddAccOp", smallUnsignedTypes,
292910037SARM gem5 Developers                      addlwCode, hi=True)
293010037SARM gem5 Developers    # UADDLP
293110037SARM gem5 Developers    twoRegCondenseInstX("uaddlp", "UaddlpDX", "SimdAddOp", smallUnsignedTypes,
293210037SARM gem5 Developers                        2, addlwCode)
293310037SARM gem5 Developers    twoRegCondenseInstX("uaddlp", "UaddlpQX", "SimdAddOp", smallUnsignedTypes,
293410037SARM gem5 Developers                        4, addlwCode)
293510037SARM gem5 Developers    # UADDLV
293610037SARM gem5 Developers    twoRegAcrossInstX("uaddlv", "UaddlvDX", "SimdAddOp",
293710037SARM gem5 Developers                      ("uint8_t", "uint16_t"), 2, addAcrossLongCode, long=True)
293810037SARM gem5 Developers    twoRegAcrossInstX("uaddlv", "UaddlvQX", "SimdAddOp",
293910037SARM gem5 Developers                      ("uint8_t", "uint16_t"), 4, addAcrossLongCode, long=True)
294010037SARM gem5 Developers    twoRegAcrossInstX("uaddlv", "UaddlvBQX", "SimdAddOp", ("uint32_t",), 4,
294110037SARM gem5 Developers                      addAcrossLongCode, doubleDest=True, long=True)
294210037SARM gem5 Developers    # UADDW
294310037SARM gem5 Developers    threeRegWideInstX("uaddw", "UaddwX", "SimdAddAccOp", smallUnsignedTypes,
294410037SARM gem5 Developers                      addlwCode)
294510037SARM gem5 Developers    threeRegWideInstX("uaddw2", "Uaddw2X", "SimdAddAccOp", smallUnsignedTypes,
294610037SARM gem5 Developers                      addlwCode, hi=True)
294710037SARM gem5 Developers    # UCVTF (fixed-point)
294810037SARM gem5 Developers    ucvtfFixedCode = fpOp % ("fplibFixedToFP<Element>(srcElem1, imm, true,"
294910037SARM gem5 Developers                             " FPCRRounding(fpscr), fpscr)")
295010037SARM gem5 Developers    twoEqualRegInstX("ucvtf", "UcvtfFixedDX", "SimdCvtOp", smallFloatTypes, 2,
295110037SARM gem5 Developers                     ucvtfFixedCode, hasImm=True)
295210037SARM gem5 Developers    twoEqualRegInstX("ucvtf", "UcvtfFixedQX", "SimdCvtOp", floatTypes, 4,
295310037SARM gem5 Developers                     ucvtfFixedCode, hasImm=True)
295410037SARM gem5 Developers    twoEqualRegInstX("ucvtf", "UcvtfFixedScX", "SimdCvtOp", floatTypes, 4,
295510037SARM gem5 Developers                     ucvtfFixedCode, hasImm=True, scalar=True)
295610037SARM gem5 Developers    # UCVTF (integer)
295710037SARM gem5 Developers    ucvtfIntCode = fpOp % ("fplibFixedToFP<Element>(srcElem1, 0, true,"
295810037SARM gem5 Developers                           " FPCRRounding(fpscr), fpscr)")
295910037SARM gem5 Developers    twoEqualRegInstX("ucvtf", "UcvtfIntDX", "SimdCvtOp", smallFloatTypes, 2,
296010037SARM gem5 Developers                     ucvtfIntCode)
296110037SARM gem5 Developers    twoEqualRegInstX("ucvtf", "UcvtfIntQX", "SimdCvtOp", floatTypes, 4,
296210037SARM gem5 Developers                     ucvtfIntCode)
296310037SARM gem5 Developers    twoEqualRegInstX("ucvtf", "UcvtfIntScX", "SimdCvtOp", floatTypes, 4,
296410037SARM gem5 Developers                     ucvtfIntCode, scalar=True)
296510037SARM gem5 Developers    # UHADD
296610037SARM gem5 Developers    threeEqualRegInstX("uhadd", "UhaddDX", "SimdAddOp", smallUnsignedTypes, 2,
296710037SARM gem5 Developers                       haddCode)
296810037SARM gem5 Developers    threeEqualRegInstX("uhadd", "UhaddQX", "SimdAddOp", smallUnsignedTypes, 4,
296910037SARM gem5 Developers                       haddCode)
297010037SARM gem5 Developers    # UHSUB
297110037SARM gem5 Developers    threeEqualRegInstX("uhsub", "UhsubDX", "SimdAddOp", smallUnsignedTypes, 2,
297210037SARM gem5 Developers                       hsubCode)
297310037SARM gem5 Developers    threeEqualRegInstX("uhsub", "UhsubQX", "SimdAddOp", smallUnsignedTypes, 4,
297410037SARM gem5 Developers                       hsubCode)
297510037SARM gem5 Developers    # UMAX
297610037SARM gem5 Developers    threeEqualRegInstX("umax", "UmaxDX", "SimdCmpOp", smallUnsignedTypes, 2,
297710037SARM gem5 Developers                       maxCode)
297810037SARM gem5 Developers    threeEqualRegInstX("umax", "UmaxQX", "SimdCmpOp", smallUnsignedTypes, 4,
297910037SARM gem5 Developers                       maxCode)
298010037SARM gem5 Developers    # UMAXP
298110037SARM gem5 Developers    threeEqualRegInstX("umaxp", "UmaxpDX", "SimdCmpOp", smallUnsignedTypes, 2,
298210037SARM gem5 Developers                       maxCode, pairwise=True)
298310037SARM gem5 Developers    threeEqualRegInstX("umaxp", "UmaxpQX", "SimdCmpOp", smallUnsignedTypes, 4,
298410037SARM gem5 Developers                       maxCode, pairwise=True)
298510037SARM gem5 Developers    # UMAXV
298610037SARM gem5 Developers    twoRegAcrossInstX("umaxv", "UmaxvDX", "SimdCmpOp", ("uint8_t", "uint16_t"),
298710037SARM gem5 Developers                      2, maxAcrossCode)
298810037SARM gem5 Developers    twoRegAcrossInstX("umaxv", "UmaxvQX", "SimdCmpOp", smallUnsignedTypes, 4,
298910037SARM gem5 Developers                      maxAcrossCode)
299010037SARM gem5 Developers    # UMIN
299110037SARM gem5 Developers    threeEqualRegInstX("umin", "UminDX", "SimdCmpOp", smallUnsignedTypes, 2,
299210037SARM gem5 Developers                       minCode)
299310037SARM gem5 Developers    threeEqualRegInstX("umin", "UminQX", "SimdCmpOp", smallUnsignedTypes, 4,
299410037SARM gem5 Developers                       minCode)
299510037SARM gem5 Developers    # UMINP
299610037SARM gem5 Developers    threeEqualRegInstX("uminp", "UminpDX", "SimdCmpOp", smallUnsignedTypes, 2,
299710037SARM gem5 Developers                       minCode, pairwise=True)
299810037SARM gem5 Developers    threeEqualRegInstX("uminp", "UminpQX", "SimdCmpOp", smallUnsignedTypes, 4,
299910037SARM gem5 Developers                       minCode, pairwise=True)
300010037SARM gem5 Developers    # UMINV
300110037SARM gem5 Developers    twoRegAcrossInstX("uminv", "UminvDX", "SimdCmpOp", ("uint8_t", "uint16_t"),
300210037SARM gem5 Developers                      2, minAcrossCode)
300310037SARM gem5 Developers    twoRegAcrossInstX("uminv", "UminvQX", "SimdCmpOp", smallUnsignedTypes, 4,
300410037SARM gem5 Developers                      minAcrossCode)
300510037SARM gem5 Developers    # UMLAL (by element)
300610037SARM gem5 Developers    threeRegLongInstX("umlal", "UmlalElemX", "SimdMultAccOp",
300710037SARM gem5 Developers                      smallUnsignedTypes, mlalCode, True, byElem=True)
300810037SARM gem5 Developers    threeRegLongInstX("umlal", "UmlalElem2X", "SimdMultAccOp",
300910037SARM gem5 Developers                      smallUnsignedTypes, mlalCode, True, byElem=True, hi=True)
301010037SARM gem5 Developers    # UMLAL (vector)
301110037SARM gem5 Developers    threeRegLongInstX("umlal", "UmlalX", "SimdMultAccOp", smallUnsignedTypes,
301210037SARM gem5 Developers                      mlalCode, True)
301310037SARM gem5 Developers    threeRegLongInstX("umlal", "Umlal2X", "SimdMultAccOp", smallUnsignedTypes,
301410037SARM gem5 Developers                      mlalCode, True, hi=True)
301510037SARM gem5 Developers    # UMLSL (by element)
301610037SARM gem5 Developers    threeRegLongInstX("umlsl", "UmlslElemX", "SimdMultAccOp",
301710037SARM gem5 Developers                      smallUnsignedTypes, mlslCode, True, byElem=True)
301810037SARM gem5 Developers    threeRegLongInstX("umlsl", "UmlslElem2X", "SimdMultAccOp",
301910037SARM gem5 Developers                      smallUnsignedTypes, mlslCode, True, byElem=True, hi=True)
302010037SARM gem5 Developers    # UMLSL (vector)
302110037SARM gem5 Developers    threeRegLongInstX("umlsl", "UmlslX", "SimdMultAccOp", smallUnsignedTypes,
302210037SARM gem5 Developers                      mlslCode, True)
302310037SARM gem5 Developers    threeRegLongInstX("umlsl", "Umlsl2X", "SimdMultAccOp", smallUnsignedTypes,
302410037SARM gem5 Developers                      mlslCode, True, hi=True)
302510037SARM gem5 Developers    # UMOV
302610037SARM gem5 Developers    insToGprInstX("umov", "UmovWX", "SimdMiscOp", smallUnsignedTypes, 4, 'W')
302710037SARM gem5 Developers    insToGprInstX("umov", "UmovXX", "SimdMiscOp", ("uint64_t",), 4, 'X')
302810037SARM gem5 Developers    # UMULL, UMULL2 (by element)
302910037SARM gem5 Developers    threeRegLongInstX("umull", "UmullElemX", "SimdMultOp", smallUnsignedTypes,
303010037SARM gem5 Developers                      mullCode, byElem=True)
303110037SARM gem5 Developers    threeRegLongInstX("umull", "UmullElem2X", "SimdMultOp", smallUnsignedTypes,
303210037SARM gem5 Developers                      mullCode, byElem=True, hi=True)
303310037SARM gem5 Developers    # UMULL, UMULL2 (vector)
303410037SARM gem5 Developers    threeRegLongInstX("umull", "UmullX", "SimdMultOp", smallUnsignedTypes,
303510037SARM gem5 Developers                      mullCode)
303610037SARM gem5 Developers    threeRegLongInstX("umull", "Umull2X", "SimdMultOp", smallUnsignedTypes,
303710037SARM gem5 Developers                      mullCode, hi=True)
303810037SARM gem5 Developers    # UQADD
303910037SARM gem5 Developers    uqaddCode = '''
304010037SARM gem5 Developers            destElem = srcElem1 + srcElem2;
304110037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
304210037SARM gem5 Developers            if (destElem < srcElem1 || destElem < srcElem2) {
304310037SARM gem5 Developers                destElem = (Element)(-1);
304410037SARM gem5 Developers                fpscr.qc = 1;
304510037SARM gem5 Developers            }
304610037SARM gem5 Developers            FpscrQc = fpscr;
304710037SARM gem5 Developers    '''
304810037SARM gem5 Developers    threeEqualRegInstX("uqadd", "UqaddDX", "SimdAddOp", smallUnsignedTypes, 2,
304910037SARM gem5 Developers                       uqaddCode)
305010037SARM gem5 Developers    threeEqualRegInstX("uqadd", "UqaddQX", "SimdAddOp", unsignedTypes, 4,
305110037SARM gem5 Developers                       uqaddCode)
305210037SARM gem5 Developers    threeEqualRegInstX("uqadd", "UqaddScX", "SimdAddOp", unsignedTypes, 4,
305310037SARM gem5 Developers                       uqaddCode, scalar=True)
305410037SARM gem5 Developers    # UQRSHL
305510037SARM gem5 Developers    uqrshlCode = '''
305610037SARM gem5 Developers            int16_t shiftAmt = (int8_t)srcElem2;
305710037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
305810037SARM gem5 Developers            if (shiftAmt < 0) {
305910037SARM gem5 Developers                shiftAmt = -shiftAmt;
306010037SARM gem5 Developers                Element rBit = 0;
306110037SARM gem5 Developers                if (shiftAmt <= sizeof(Element) * 8)
306210037SARM gem5 Developers                    rBit = bits(srcElem1, shiftAmt - 1);
306310037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
306410037SARM gem5 Developers                    shiftAmt = sizeof(Element) * 8 - 1;
306510037SARM gem5 Developers                    destElem = 0;
306610037SARM gem5 Developers                } else {
306710037SARM gem5 Developers                    destElem = (srcElem1 >> shiftAmt);
306810037SARM gem5 Developers                }
306910037SARM gem5 Developers                destElem += rBit;
307010037SARM gem5 Developers            } else {
307110037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
307210037SARM gem5 Developers                    if (srcElem1 != 0) {
307310037SARM gem5 Developers                        destElem = mask(sizeof(Element) * 8);
307410037SARM gem5 Developers                        fpscr.qc = 1;
307510037SARM gem5 Developers                    } else {
307610037SARM gem5 Developers                        destElem = 0;
307710037SARM gem5 Developers                    }
307810037SARM gem5 Developers                } else {
307910037SARM gem5 Developers                    if (bits(srcElem1, sizeof(Element) * 8 - 1,
308010037SARM gem5 Developers                                sizeof(Element) * 8 - shiftAmt)) {
308110037SARM gem5 Developers                        destElem = mask(sizeof(Element) * 8);
308210037SARM gem5 Developers                        fpscr.qc = 1;
308310037SARM gem5 Developers                    } else {
308410037SARM gem5 Developers                        destElem = srcElem1 << shiftAmt;
308510037SARM gem5 Developers                    }
308610037SARM gem5 Developers                }
308710037SARM gem5 Developers            }
308810037SARM gem5 Developers            FpscrQc = fpscr;
308910037SARM gem5 Developers    '''
309010037SARM gem5 Developers    threeEqualRegInstX("uqrshl", "UqrshlDX", "SimdCmpOp", smallUnsignedTypes,
309110037SARM gem5 Developers                       2, uqrshlCode)
309210037SARM gem5 Developers    threeEqualRegInstX("uqrshl", "UqrshlQX", "SimdCmpOp", unsignedTypes, 4,
309310037SARM gem5 Developers                       uqrshlCode)
309410037SARM gem5 Developers    threeEqualRegInstX("uqrshl", "UqrshlScX", "SimdCmpOp", unsignedTypes, 4,
309510037SARM gem5 Developers                       uqrshlCode, scalar=True)
309610037SARM gem5 Developers    # UQRSHRN
309710037SARM gem5 Developers    uqrshrnCode = '''
309810037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
309910037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
310010037SARM gem5 Developers                if (srcElem1 != 0)
310110037SARM gem5 Developers                    fpscr.qc = 1;
310210037SARM gem5 Developers                destElem = 0;
310310037SARM gem5 Developers            } else if (imm) {
310410037SARM gem5 Developers                BigElement mid = (srcElem1 >> (imm - 1));
310510037SARM gem5 Developers                uint64_t rBit = mid & 0x1;
310610037SARM gem5 Developers                mid >>= 1;
310710037SARM gem5 Developers                mid += rBit;
310810037SARM gem5 Developers                if (mid != (Element)mid) {
310910037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8);
311010037SARM gem5 Developers                    fpscr.qc = 1;
311110037SARM gem5 Developers                } else {
311210037SARM gem5 Developers                    destElem = mid;
311310037SARM gem5 Developers                }
311410037SARM gem5 Developers            } else {
311510037SARM gem5 Developers                if (srcElem1 != (Element)srcElem1) {
311610037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8 - 1);
311710037SARM gem5 Developers                    fpscr.qc = 1;
311810037SARM gem5 Developers                } else {
311910037SARM gem5 Developers                    destElem = srcElem1;
312010037SARM gem5 Developers                }
312110037SARM gem5 Developers            }
312210037SARM gem5 Developers            FpscrQc = fpscr;
312310037SARM gem5 Developers    '''
312410037SARM gem5 Developers    twoRegNarrowInstX("uqrshrn", "UqrshrnX", "SimdShiftOp", smallUnsignedTypes,
312510037SARM gem5 Developers                      uqrshrnCode, hasImm=True)
312610037SARM gem5 Developers    twoRegNarrowInstX("uqrshrn2", "Uqrshrn2X", "SimdShiftOp",
312710037SARM gem5 Developers                      smallUnsignedTypes, uqrshrnCode, hasImm=True, hi=True)
312810037SARM gem5 Developers    twoRegNarrowInstX("uqrshrn", "UqrshrnScX", "SimdShiftOp",
312910037SARM gem5 Developers                      smallUnsignedTypes, uqrshrnCode, hasImm=True,
313010037SARM gem5 Developers                      scalar=True)
313110037SARM gem5 Developers    # UQSHL (immediate)
313210037SARM gem5 Developers    uqshlImmCode = '''
313310037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
313410037SARM gem5 Developers            if (imm >= sizeof(Element) * 8) {
313510037SARM gem5 Developers                if (srcElem1 != 0) {
313610037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8);
313710037SARM gem5 Developers                    fpscr.qc = 1;
313810037SARM gem5 Developers                } else {
313910037SARM gem5 Developers                    destElem = 0;
314010037SARM gem5 Developers                }
314110037SARM gem5 Developers            } else if (imm) {
314210037SARM gem5 Developers                destElem = (srcElem1 << imm);
314310037SARM gem5 Developers                uint64_t topBits = bits((uint64_t)srcElem1,
314410037SARM gem5 Developers                                        sizeof(Element) * 8 - 1,
314510037SARM gem5 Developers                                        sizeof(Element) * 8 - imm);
314610037SARM gem5 Developers                if (topBits != 0) {
314710037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8);
314810037SARM gem5 Developers                    fpscr.qc = 1;
314910037SARM gem5 Developers                }
315010037SARM gem5 Developers            } else {
315110037SARM gem5 Developers                destElem = srcElem1;
315210037SARM gem5 Developers            }
315310037SARM gem5 Developers            FpscrQc = fpscr;
315410037SARM gem5 Developers    '''
315510037SARM gem5 Developers    twoEqualRegInstX("uqshl", "UqshlImmDX", "SimdAluOp", smallUnsignedTypes, 2,
315610037SARM gem5 Developers                     uqshlImmCode, hasImm=True)
315710037SARM gem5 Developers    twoEqualRegInstX("uqshl", "UqshlImmQX", "SimdAluOp", unsignedTypes, 4,
315810037SARM gem5 Developers                     uqshlImmCode, hasImm=True)
315910037SARM gem5 Developers    twoEqualRegInstX("uqshl", "UqshlImmScX", "SimdAluOp", unsignedTypes, 4,
316010037SARM gem5 Developers                     uqshlImmCode, hasImm=True, scalar=True)
316110037SARM gem5 Developers    # UQSHL (register)
316210037SARM gem5 Developers    uqshlCode = '''
316310037SARM gem5 Developers            int16_t shiftAmt = (int8_t)srcElem2;
316410037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
316510037SARM gem5 Developers            if (shiftAmt < 0) {
316610037SARM gem5 Developers                shiftAmt = -shiftAmt;
316710037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
316810037SARM gem5 Developers                    shiftAmt = sizeof(Element) * 8 - 1;
316910037SARM gem5 Developers                    destElem = 0;
317010037SARM gem5 Developers                } else {
317110037SARM gem5 Developers                    destElem = (srcElem1 >> shiftAmt);
317210037SARM gem5 Developers                }
317310037SARM gem5 Developers            } else if (shiftAmt > 0) {
317410037SARM gem5 Developers                if (shiftAmt >= sizeof(Element) * 8) {
317510037SARM gem5 Developers                    if (srcElem1 != 0) {
317610037SARM gem5 Developers                        destElem = mask(sizeof(Element) * 8);
317710037SARM gem5 Developers                        fpscr.qc = 1;
317810037SARM gem5 Developers                    } else {
317910037SARM gem5 Developers                        destElem = 0;
318010037SARM gem5 Developers                    }
318110037SARM gem5 Developers                } else {
318210037SARM gem5 Developers                    if (bits(srcElem1, sizeof(Element) * 8 - 1,
318310037SARM gem5 Developers                                sizeof(Element) * 8 - shiftAmt)) {
318410037SARM gem5 Developers                        destElem = mask(sizeof(Element) * 8);
318510037SARM gem5 Developers                        fpscr.qc = 1;
318610037SARM gem5 Developers                    } else {
318710037SARM gem5 Developers                        destElem = srcElem1 << shiftAmt;
318810037SARM gem5 Developers                    }
318910037SARM gem5 Developers                }
319010037SARM gem5 Developers            } else {
319110037SARM gem5 Developers                destElem = srcElem1;
319210037SARM gem5 Developers            }
319310037SARM gem5 Developers            FpscrQc = fpscr;
319410037SARM gem5 Developers    '''
319510037SARM gem5 Developers    threeEqualRegInstX("uqshl", "UqshlDX", "SimdAluOp", smallUnsignedTypes, 2,
319610037SARM gem5 Developers                       uqshlCode)
319710037SARM gem5 Developers    threeEqualRegInstX("uqshl", "UqshlQX", "SimdAluOp", unsignedTypes, 4,
319810037SARM gem5 Developers                       uqshlCode)
319910037SARM gem5 Developers    threeEqualRegInstX("uqshl", "UqshlScX", "SimdAluOp", unsignedTypes, 4,
320010037SARM gem5 Developers                       uqshlCode, scalar=True)
320110037SARM gem5 Developers    # UQSHRN, UQSHRN2
320210037SARM gem5 Developers    uqshrnCode = '''
320310037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
320410037SARM gem5 Developers            if (imm > sizeof(srcElem1) * 8) {
320510037SARM gem5 Developers                if (srcElem1 != 0)
320610037SARM gem5 Developers                    fpscr.qc = 1;
320710037SARM gem5 Developers                destElem = 0;
320810037SARM gem5 Developers            } else if (imm) {
320910037SARM gem5 Developers                BigElement mid = ((srcElem1 >> (imm - 1)) >> 1);
321010037SARM gem5 Developers                if (mid != (Element)mid) {
321110037SARM gem5 Developers                    destElem = mask(sizeof(Element) * 8);
321210037SARM gem5 Developers                    fpscr.qc = 1;
321310037SARM gem5 Developers                } else {
321410037SARM gem5 Developers                    destElem = mid;
321510037SARM gem5 Developers                }
321610037SARM gem5 Developers            } else {
321710037SARM gem5 Developers                destElem = srcElem1;
321810037SARM gem5 Developers            }
321910037SARM gem5 Developers            FpscrQc = fpscr;
322010037SARM gem5 Developers    '''
322110037SARM gem5 Developers    twoRegNarrowInstX("uqshrn", "UqshrnX", "SimdShiftOp", smallUnsignedTypes,
322210037SARM gem5 Developers                      uqshrnCode, hasImm=True)
322310037SARM gem5 Developers    twoRegNarrowInstX("uqshrn2", "Uqshrn2X", "SimdShiftOp", smallUnsignedTypes,
322410037SARM gem5 Developers                      uqshrnCode, hasImm=True, hi=True)
322510037SARM gem5 Developers    twoRegNarrowInstX("uqshrn", "UqshrnScX", "SimdShiftOp", smallUnsignedTypes,
322610037SARM gem5 Developers                      uqshrnCode, hasImm=True, scalar=True)
322710037SARM gem5 Developers    # UQSUB
322810037SARM gem5 Developers    uqsubCode = '''
322910037SARM gem5 Developers            destElem = srcElem1 - srcElem2;
323010037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
323110037SARM gem5 Developers            if (destElem > srcElem1) {
323210037SARM gem5 Developers                destElem = 0;
323310037SARM gem5 Developers                fpscr.qc = 1;
323410037SARM gem5 Developers            }
323510037SARM gem5 Developers            FpscrQc = fpscr;
323610037SARM gem5 Developers    '''
323710037SARM gem5 Developers    threeEqualRegInstX("uqsub", "UqsubDX", "SimdAddOp", smallUnsignedTypes, 2,
323810037SARM gem5 Developers                       uqsubCode)
323910037SARM gem5 Developers    threeEqualRegInstX("uqsub", "UqsubQX", "SimdAddOp", unsignedTypes, 4,
324010037SARM gem5 Developers                       uqsubCode)
324110037SARM gem5 Developers    threeEqualRegInstX("uqsub", "UqsubScX", "SimdAddOp", unsignedTypes, 4,
324210037SARM gem5 Developers                       uqsubCode, scalar=True)
324310037SARM gem5 Developers    # UQXTN
324410037SARM gem5 Developers    uqxtnCode = '''
324510037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
324610037SARM gem5 Developers            destElem = srcElem1;
324710037SARM gem5 Developers            if ((BigElement)destElem != srcElem1) {
324810037SARM gem5 Developers                fpscr.qc = 1;
324910037SARM gem5 Developers                destElem = mask(sizeof(Element) * 8);
325010037SARM gem5 Developers            }
325110037SARM gem5 Developers            FpscrQc = fpscr;
325210037SARM gem5 Developers    '''
325310037SARM gem5 Developers    twoRegNarrowInstX("uqxtn", "UqxtnX", "SimdMiscOp", smallUnsignedTypes,
325410037SARM gem5 Developers                      uqxtnCode)
325510037SARM gem5 Developers    twoRegNarrowInstX("uqxtn", "Uqxtn2X", "SimdMiscOp", smallUnsignedTypes,
325610037SARM gem5 Developers                      uqxtnCode, hi=True)
325710037SARM gem5 Developers    twoRegNarrowInstX("uqxtn", "UqxtnScX", "SimdMiscOp", smallUnsignedTypes,
325810037SARM gem5 Developers                      uqxtnCode, scalar=True)
325910037SARM gem5 Developers    # URECPE
326010037SARM gem5 Developers    urecpeCode = "destElem = unsignedRecipEstimate(srcElem1);"
326110037SARM gem5 Developers    twoEqualRegInstX("urecpe", "UrecpeDX", "SimdMultAccOp", ("uint32_t",), 2,
326210037SARM gem5 Developers                     urecpeCode)
326310037SARM gem5 Developers    twoEqualRegInstX("urecpe", "UrecpeQX", "SimdMultAccOp", ("uint32_t",), 4,
326410037SARM gem5 Developers                     urecpeCode)
326510037SARM gem5 Developers    # URHADD
326610037SARM gem5 Developers    threeEqualRegInstX("urhadd", "UrhaddDX", "SimdAddOp", smallUnsignedTypes,
326710037SARM gem5 Developers                       2, rhaddCode)
326810037SARM gem5 Developers    threeEqualRegInstX("urhadd", "UrhaddQX", "SimdAddOp", smallUnsignedTypes,
326910037SARM gem5 Developers                       4, rhaddCode)
327010037SARM gem5 Developers    # URSHL
327110037SARM gem5 Developers    threeEqualRegInstX("urshl", "UrshlDX", "SimdShiftOp", unsignedTypes, 2,
327210037SARM gem5 Developers                       rshlCode)
327310037SARM gem5 Developers    threeEqualRegInstX("urshl", "UrshlQX", "SimdShiftOp", unsignedTypes, 4,
327410037SARM gem5 Developers                       rshlCode)
327510037SARM gem5 Developers    # URSHR
327610037SARM gem5 Developers    twoEqualRegInstX("urshr", "UrshrDX", "SimdShiftOp", unsignedTypes, 2,
327710037SARM gem5 Developers                     rshrCode, hasImm=True)
327810037SARM gem5 Developers    twoEqualRegInstX("urshr", "UrshrQX", "SimdShiftOp", unsignedTypes, 4,
327910037SARM gem5 Developers                     rshrCode, hasImm=True)
328010037SARM gem5 Developers    # URSQRTE
328110037SARM gem5 Developers    ursqrteCode = "destElem = unsignedRSqrtEstimate(srcElem1);"
328210037SARM gem5 Developers    twoEqualRegInstX("ursqrte", "UrsqrteDX", "SimdSqrtOp", ("uint32_t",), 2,
328310037SARM gem5 Developers                     ursqrteCode)
328410037SARM gem5 Developers    twoEqualRegInstX("ursqrte", "UrsqrteQX", "SimdSqrtOp", ("uint32_t",), 4,
328510037SARM gem5 Developers                     ursqrteCode)
328610037SARM gem5 Developers    # URSRA
328710037SARM gem5 Developers    twoEqualRegInstX("ursra", "UrsraDX", "SimdShiftOp", unsignedTypes, 2,
328810037SARM gem5 Developers                     rsraCode, True, hasImm=True)
328910037SARM gem5 Developers    twoEqualRegInstX("ursra", "UrsraQX", "SimdShiftOp", unsignedTypes, 4,
329010037SARM gem5 Developers                     rsraCode, True, hasImm=True)
329110037SARM gem5 Developers    # USHL
329210037SARM gem5 Developers    threeEqualRegInstX("ushl", "UshlDX", "SimdShiftOp", unsignedTypes, 2,
329310037SARM gem5 Developers                       shlCode)
329410037SARM gem5 Developers    threeEqualRegInstX("ushl", "UshlQX", "SimdShiftOp", unsignedTypes, 4,
329510037SARM gem5 Developers                       shlCode)
329610037SARM gem5 Developers    # USHLL, USHLL2
329710037SARM gem5 Developers    twoRegLongInstX("ushll", "UshllX", "SimdShiftOp", smallUnsignedTypes,
329810037SARM gem5 Developers                    shllCode, hasImm=True)
329910037SARM gem5 Developers    twoRegLongInstX("ushll", "Ushll2X", "SimdShiftOp", smallUnsignedTypes,
330010037SARM gem5 Developers                    shllCode, hi=True, hasImm=True)
330110037SARM gem5 Developers    # USHR
330210037SARM gem5 Developers    twoEqualRegInstX("ushr", "UshrDX", "SimdShiftOp", unsignedTypes, 2,
330310037SARM gem5 Developers                     shrCode, hasImm=True)
330410037SARM gem5 Developers    twoEqualRegInstX("ushr", "UshrQX", "SimdShiftOp", unsignedTypes, 4,
330510037SARM gem5 Developers                     shrCode, hasImm=True)
330610037SARM gem5 Developers    # USQADD
330710037SARM gem5 Developers    usqaddCode = '''
330810037SARM gem5 Developers            FPSCR fpscr = (FPSCR) FpscrQc;
330910037SARM gem5 Developers            Element tmp = destElem + srcElem1;
331010037SARM gem5 Developers            if (bits(srcElem1, sizeof(Element) * 8 - 1) == 0) {
331110037SARM gem5 Developers                if (tmp < srcElem1 || tmp < destElem) {
331210037SARM gem5 Developers                    destElem = (Element)(-1);
331310037SARM gem5 Developers                    fpscr.qc = 1;
331410037SARM gem5 Developers                } else {
331510037SARM gem5 Developers                    destElem = tmp;
331610037SARM gem5 Developers                }
331710037SARM gem5 Developers            } else {
331810037SARM gem5 Developers                Element absSrcElem1 = (~srcElem1) + 1;
331910037SARM gem5 Developers                if (absSrcElem1 > destElem) {
332010037SARM gem5 Developers                    destElem = 0;
332110037SARM gem5 Developers                    fpscr.qc = 1;
332210037SARM gem5 Developers                } else {
332310037SARM gem5 Developers                    destElem = tmp;
332410037SARM gem5 Developers                }
332510037SARM gem5 Developers            }
332610037SARM gem5 Developers            FpscrQc = fpscr;
332710037SARM gem5 Developers    '''
332810037SARM gem5 Developers    twoEqualRegInstX("usqadd", "UsqaddDX", "SimdAddOp", smallUnsignedTypes, 2,
332910037SARM gem5 Developers                     usqaddCode, True)
333010037SARM gem5 Developers    twoEqualRegInstX("usqadd", "UsqaddQX", "SimdAddOp", unsignedTypes, 4,
333110037SARM gem5 Developers                     usqaddCode, True)
333210037SARM gem5 Developers    twoEqualRegInstX("usqadd", "UsqaddScX", "SimdAddOp", unsignedTypes, 4,
333310037SARM gem5 Developers                     usqaddCode, True, scalar=True)
333410037SARM gem5 Developers    # USRA
333510037SARM gem5 Developers    twoEqualRegInstX("usra", "UsraDX", "SimdShiftOp", unsignedTypes, 2,
333610037SARM gem5 Developers                     sraCode, True, hasImm=True)
333710037SARM gem5 Developers    twoEqualRegInstX("usra", "UsraQX", "SimdShiftOp", unsignedTypes, 4,
333810037SARM gem5 Developers                     sraCode, True, hasImm=True)
333910037SARM gem5 Developers    # USUBL
334010037SARM gem5 Developers    threeRegLongInstX("usubl", "UsublX", "SimdAddOp", smallUnsignedTypes,
334110037SARM gem5 Developers                      sublwCode)
334210037SARM gem5 Developers    threeRegLongInstX("usubl2", "Usubl2X", "SimdAddOp", smallUnsignedTypes,
334310037SARM gem5 Developers                      sublwCode, hi=True)
334410037SARM gem5 Developers    # USUBW
334510037SARM gem5 Developers    threeRegWideInstX("usubw", "UsubwX", "SimdAddOp", smallUnsignedTypes,
334610037SARM gem5 Developers                      sublwCode)
334710037SARM gem5 Developers    threeRegWideInstX("usubw2", "Usubw2X", "SimdAddOp", smallUnsignedTypes,
334810037SARM gem5 Developers                      sublwCode, hi=True)
334910037SARM gem5 Developers    # UXTL -> alias to USHLL
335010037SARM gem5 Developers    # UZP1
335110037SARM gem5 Developers    uzpCode = '''
335210037SARM gem5 Developers        unsigned part = %s;
335310037SARM gem5 Developers        for (unsigned i = 0; i < eCount / 2; i++) {
335410037SARM gem5 Developers            destReg.elements[i] = srcReg1.elements[2 * i + part];
335510037SARM gem5 Developers            destReg.elements[eCount / 2 + i] = srcReg2.elements[2 * i + part];
335610037SARM gem5 Developers        }
335710037SARM gem5 Developers    '''
335810037SARM gem5 Developers    threeRegScrambleInstX("Uzp1", "Uzp1DX", "SimdAluOp", smallUnsignedTypes, 2,
335910037SARM gem5 Developers                          uzpCode % "0")
336010037SARM gem5 Developers    threeRegScrambleInstX("Uzp1", "Uzp1QX", "SimdAluOp", unsignedTypes, 4,
336110037SARM gem5 Developers                          uzpCode % "0")
336210037SARM gem5 Developers    # UZP2
336310037SARM gem5 Developers    threeRegScrambleInstX("Uzp2", "Uzp2DX", "SimdAluOp", smallUnsignedTypes, 2,
336410037SARM gem5 Developers                          uzpCode % "1")
336510037SARM gem5 Developers    threeRegScrambleInstX("Uzp2", "Uzp2QX", "SimdAluOp", unsignedTypes, 4,
336610037SARM gem5 Developers                          uzpCode % "1")
336710037SARM gem5 Developers    # XTN, XTN2
336810037SARM gem5 Developers    xtnCode = "destElem = srcElem1;"
336910037SARM gem5 Developers    twoRegNarrowInstX("Xtn", "XtnX", "SimdMiscOp", smallUnsignedTypes, xtnCode)
337010037SARM gem5 Developers    twoRegNarrowInstX("Xtn", "Xtn2X", "SimdMiscOp", smallUnsignedTypes,
337110037SARM gem5 Developers                      xtnCode, hi=True)
337210037SARM gem5 Developers    # ZIP1
337310037SARM gem5 Developers    zipCode = '''
337410037SARM gem5 Developers        unsigned base = %s;
337510037SARM gem5 Developers        for (unsigned i = 0; i < eCount / 2; i++) {
337610037SARM gem5 Developers            destReg.elements[2 * i] = srcReg1.elements[base + i];
337710037SARM gem5 Developers            destReg.elements[2 * i + 1] = srcReg2.elements[base + i];
337810037SARM gem5 Developers        }
337910037SARM gem5 Developers    '''
338010037SARM gem5 Developers    threeRegScrambleInstX("zip1", "Zip1DX", "SimdAluOp", smallUnsignedTypes, 2,
338110037SARM gem5 Developers                          zipCode % "0")
338210037SARM gem5 Developers    threeRegScrambleInstX("zip1", "Zip1QX", "SimdAluOp", unsignedTypes, 4,
338310037SARM gem5 Developers                          zipCode % "0")
338410037SARM gem5 Developers    # ZIP2
338510037SARM gem5 Developers    threeRegScrambleInstX("zip2", "Zip2DX", "SimdAluOp", smallUnsignedTypes, 2,
338610037SARM gem5 Developers                          zipCode % "eCount / 2")
338710037SARM gem5 Developers    threeRegScrambleInstX("zip2", "Zip2QX", "SimdAluOp", unsignedTypes, 4,
338810037SARM gem5 Developers                          zipCode % "eCount / 2")
338910037SARM gem5 Developers
339011165SRekai.GonzalezAlberquilla@arm.com    for decoderFlavour, type_dict in decoders.iteritems():
339111165SRekai.GonzalezAlberquilla@arm.com        header_output += '''
339211165SRekai.GonzalezAlberquilla@arm.com        class %(decoder_flavour)sDecoder {
339311165SRekai.GonzalezAlberquilla@arm.com        public:
339411165SRekai.GonzalezAlberquilla@arm.com        ''' % { "decoder_flavour" : decoderFlavour }
339511165SRekai.GonzalezAlberquilla@arm.com        for type,name in type_dict.iteritems():
339611165SRekai.GonzalezAlberquilla@arm.com            header_output += '''
339711165SRekai.GonzalezAlberquilla@arm.com            template<typename Elem> using %(type)s = %(new_name)s<Elem>;''' % {
339811165SRekai.GonzalezAlberquilla@arm.com               "type" : type, "new_name" : name
339911165SRekai.GonzalezAlberquilla@arm.com            }
340011165SRekai.GonzalezAlberquilla@arm.com        header_output += '''
340111165SRekai.GonzalezAlberquilla@arm.com        };'''
340210037SARM gem5 Developers}};
3403